前向声明 类 时成员函数的行为
Behaviour of member functions when forward declaring classes
当使用 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 声明中实现时,如下所示:
class University
{
vector <Student*> students;
public:
University();
void print() { for (auto s: students) cout << s << '\n'; }
};
打印输出变为
0x20055ff0
0x20056028
问题:为什么 print()
函数的行为是这样的,即使 Student
已在第一行声明?
解决方案:在实现任何成员函数之前声明所有classes。只要 print()
和 operator <<
都在它们的 classes 声明之后实现,即使 print()
在 operator <<
[=21= 之前实现,它也能正常工作]
使用 operator<<
打印指针的默认行为是打印所指向的内存地址的十六进制表示。
当 print()
的实现在 class 声明中时,编译器还没有看到 Student*
指针的 operator<<
覆盖,所以它不会'我不知道它的行为应该与默认行为有任何不同。
当您在 operator<<
覆盖之后定义 print()
实现时,编译器知道使用该覆盖而不是默认值。
当使用 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 声明中实现时,如下所示:
class University
{
vector <Student*> students;
public:
University();
void print() { for (auto s: students) cout << s << '\n'; }
};
打印输出变为
0x20055ff0
0x20056028
问题:为什么 print()
函数的行为是这样的,即使 Student
已在第一行声明?
解决方案:在实现任何成员函数之前声明所有classes。只要 print()
和 operator <<
都在它们的 classes 声明之后实现,即使 print()
在 operator <<
[=21= 之前实现,它也能正常工作]
使用 operator<<
打印指针的默认行为是打印所指向的内存地址的十六进制表示。
当 print()
的实现在 class 声明中时,编译器还没有看到 Student*
指针的 operator<<
覆盖,所以它不会'我不知道它的行为应该与默认行为有任何不同。
当您在 operator<<
覆盖之后定义 print()
实现时,编译器知道使用该覆盖而不是默认值。