我想知道为什么静态对象在这个例子中调用了父方法和动态对象子方法。
#include <string>
#include <iostream>
using namespace std;
class Father {
public:
virtual string Info() {
return "I am father";
}
};
class Son : public Father {
public:
string Info() {
return "I am son";
}
};
int main() {
Father f = Son();
cout << f.Info(); // I am father
Father* pf = new Son();
cout << pf->Info(); // I am son
return 0;
}
答案 0 :(得分:7)
归因于slicing - 您的f
实际上是自动定位Father
,分配Father f = Son()
实际上是Father f = Father(Son())
,因此{{1}动态类型确实是f
,正如预期的那样,Father
将被调用。
有关切片的更多信息,请参阅this post
答案 1 :(得分:1)
这是多态性。当您静态分配对象时:
Son son();
您在编译时知道son
的类型为Son
。如果您动态分配它,则可以选择在Son
指针或Son
指针中存储Father
个对象。如果将它们存储在Son
指针中,那么它与上面的相同。但是,如果将Son
对象存储在Father
类型指针中:
Father* ptr = new Son()
然后编译器无法知道哪个类型的对象Father
指针指向。因此,在运行时,它发现它调用适当版本的Info
。
答案 2 :(得分:1)
因为,Father f = Son()
创建父类型的对象并从对象Son复制属性(在这种情况下没有要复制的属性),所以Father * pf = new Son()
接收指向对象Son的指针,它实际上可能是任何父亲 - 派生对象。
最后,在您的示例中,您有3个对象。复制到Father f
的{{1}},unnamed object Son()
和指向Son类型对象的Father f
。