Search code examples
c++initializationoutput

C++ Calling return member function outputs "?before initialization"


When I run this code, I get this output.

main.cpp

#include <iostream>
#include "Date.h"
#include <string>

int main()
{
    //Create
    Date date = Date(1 , 1, 2000);
    std::string str = date.GetDate();
    std::cout << "Initial parameters: " << str << "\n";

    //Use setters to change
    date.SetDay(30);
    date.SetMonth(5);
    date.SetYear(1999);
    std::cout << "Used setters: " << date.GetDate() << "\n";

    //Input invalid parameters
    date.SetDay(0);
    date.SetMonth(13);
    std::cout << "Set day to 0, month to 13: " << date.GetDate() << "\n";
}

Date.h

#ifndef DATE_H
#define DATE_H

#include <string>

class Date {
public:
    Date(unsigned int, unsigned int, int);
    void SetMonth(unsigned int);
    void SetDay(unsigned int);
    void SetYear(int);
    std::string GetDate() const;
    unsigned int GetMonth() const;
    unsigned int GetDay() const;
    int GetYear() const;

private:
    unsigned int month{ 1 };
    unsigned int day{ 1 };
    int year{ 0 };
};

#endif

Date.cpp

#include "Date.h"
#include <string>

Date::Date(unsigned int month, unsigned int day, int year) {
    SetMonth(month);
    SetDay(day);
    SetYear(year);
}

void Date::SetMonth(unsigned int month) {
    if (month > 12 || month < 1) this->month = 1;
    else this->month = month;
}

void Date::SetDay(unsigned int day) {
    if (day < 1) this->day = 1;
    else this->day = day; //TODO upper day limit (not for this exercise though hahahahaaaa)
}

void Date::SetYear(int year) {
    this->year = year;
}

std::string Date::GetDate() const {
    std::string output;
    output = GetMonth();
    output += "/" + GetDay();
    output += "/" + GetYear();
    return output;
}

unsigned int Date::GetMonth() const { return month; }

unsigned int Date::GetDay() const { return day; }

int Date::GetYear() const { return year; }

enter image description here

TLDR main.cpp lines 12, 18, and 23 call the member function GetDate() - prototyped Date.h line 12 and defined Date.cpp line 24 - on an object of my custom Date class. Instead of outputting what it's supposed to, it outputs "?before initialization".

In place of date.GetDate() it prints "?before initialization". What is before initialization? The function? The member fields are all initialized. In fact, if I call and output just one of the member fields, such as std::cout << date.GetDay(), it prints just fine. And why does it print a smiley face or a club?


Solution

  • The + operator in "/" + GetDay() and "/" + GetYear() are not concatenating strings but moving the pointer pointing at the first element of the array "/" ({'/', '\0'}) GetDay() and GetYear() elements ahead.

    GetYear() returns a large value, so the pointer goes to some "random" position and before initialization seems happened to be there. It should be used in somewhere else in the library used.

    Instead of this, you can use std::stringstream to concatenate strings and integers like this:

    #include <sstream>
    
    std::string Date::GetDate() const {
        std::stringstream output;
        output << GetMonth();
        output << "/" << GetDay();
        output << "/" << GetYear();
        return output.str();
    }