Когда следующий код скомпилирован с помощью 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 <<
.
operator <<
перегрузки дляStudent&
, тоprint()
выведет шестнадцатеричные адреса; ошибки компиляции не будет. К сожалению, я должен использоватьStudent*
, потому чтоvector <Student&>
в классеUniversity
будет ошибкой компиляции. - person visitor   schedule 28.04.2018cout << *s
. Честно говоря, использование необработанных указателей, подобных этому, само по себе является кошмаром, потому что теперь вы должны помнить об их удалении в своем деструкторе. - person Gem Taylor   schedule 30.04.2018cout << *s
, но есть ли способ избежать необработанных указателей, таких какStudent*
, когдаvector
не может содержать ссылки? У меня тоже не может бытьvector <Student>
, так как я не хочу, чтобыStudent
удалялись при удаленииUniversity
. - person visitor   schedule 02.05.2018