Поведение функций-членов при объявлении классов вперед - PullRequest
0 голосов
/ 27 апреля 2018

Когда следующий код скомпилирован с C ++ 11, он ведет себя как ожидалось.

class Student;

class University
{
    vector <Student*> students;
public:
    University();
    void print();
};

class Student
{
    string name;
public:
    Student(string nom) : name(nom) {}
    friend ostream& operator << (ostream& out, Student* S)
    {
        return out << S -> name;
    }
};

University::University()
{
    for (string name: {"Alice", "Bob"})
        students.push_back(new Student(name));
}

void University::print() { for (auto s: students) cout << s << '\n'; }

int main()
{
    University uni;
    uni.print();
}

Распечатка

Alice
Bob

Однако, когда функция print () реализована внутри объявления класса следующим образом:

class University
{
    vector <Student*> students;
public:
    University();
    void print() { for (auto s: students) cout << s << '\n'; }
};

Распечатка становится

0x20055ff0
0x20056028

Вопрос : Почему функция print() ведет себя так, хотя Student было объявлено в самой первой строке?

Решение : Объявите все классы перед реализацией любой из их функций-членов. До тех пор, пока print() и operator << будут реализованы после объявления их классов, print() будет работать правильно, даже если он реализован до operator <<

1 Ответ

0 голосов
/ 27 апреля 2018

Поведение по умолчанию печати указателя с operator<< состоит в печати шестнадцатеричного представления адреса памяти, на который указывает.

Когда реализация print() находится внутри объявления класса, компилятор еще не видел переопределения operator<< для указателя Student*, поэтому он не знает, что он должен вести себя иначе, чем по умолчанию.

Когда вы определяете реализацию print() после переопределения operator<<, компилятор знает, что использовать это переопределение вместо значения по умолчанию.

...