前向声明类时成员函数的行为

vis*_*tor 1 c++ class forward-declaration c++11

当使用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();
}
Run Code Online (Sandbox Code Playgroud)

打印输出是

Alice
Bob
Run Code Online (Sandbox Code Playgroud)

但是,当print()函数在其类声明中实现时,如下所示:

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

打印输出成为

0x20055ff0
0x20056028
Run Code Online (Sandbox Code Playgroud)

问题:为什么print()函数的行为如此,即使Student已经在第一行声明了?

解决方案:在实现任何成员函数之前声明所有类.只要print()并且operator <<都在它们的类声明之后实现,print()即使它之前已经实现也能正常工作operator <<

小智 6

打印指针的默认行为是打印指向operator<<的内存地址的十六进制表示.

当实现print()在类声明中时,编译器还没有看到指针的operator<<覆盖Student*,因此它不知道它的行为应该与默认值不同.

在覆盖print()之后定义实现时operator<<,编译器知道使用该覆盖而不是默认.