我的c ++代码出现问题..
class GrandParent {
public:
GrandParent()
{
printMe();
}
virtual void printMe()
{
std::cout << "GrandParent: printme" << std::endl;
}
}
class Parent : public GrandParent {
public:
Parent(){}
virtual void printMe()
{
std::cout << "Parent: printMe!" << std::endl;
}
}
class Child : public Parent {
public:
Child(){}
void printMe()
{
std::cout << "Child: printMe!" << std::endl;
}
}
int main()
{
Child *p = new Child();
delete p;
}
当我运行此代码时,它会打印&#34; GrandParent:printMe&#34;。 我的目标是打印&#34; Child:printMe!&#34;。覆盖printMe有什么问题吗?
答案 0 :(得分:4)
你想要做的是不可能的。在GrandParent
的构造函数时,已构造和初始化的Child
对象的唯一部分是GrandParent
部分 - 包括vtable。也就是说,当您致电printMe()
时,该条目将为GrandParent
。只有在构建Child
之后,printMe()
的vtable条目才会更新为指向Child::printMe
。
请注意,C ++的工作方式很好。如果Child::printMe
已经被调用的那个,那么你将在一个尚未构造的对象上调用一个成员函数。没有什么好处可以来。
答案 1 :(得分:1)
简短回答:这就是C ++的工作方式。
从构造函数调用虚方法时,不使用运行时类的方法。而是使用编译时类的方法。
但使用Curiously Recurring Template Pattern显示的here可能会导致转义:
#include <iostream>
template <class T>
class Base
{
protected:
Base()
{
T::printMe();
}
};
class GrandParent : Base<GrandParent>
{
public:
GrandParent()
: Base<GrandParent>()
{}
static void printMe()
{
std::cout << "GrandParent: printMe!" << std::endl;
}
};
class Parent : public GrandParent, public Base<Parent>
{
public:
Parent()
{}
static void printMe()
{
std::cout << "Parent: printMe!" << std::endl;
}
};
class Child : public Parent, public Base<Child>
{
public:
Child()
{}
static void printMe()
{
std::cout << "Child: printMe!" << std::endl;
}
};
int main()
{
GrandParent a;
std::cout << "..." << std::endl;
Parent b;
std::cout << "..." << std::endl;
Child c;
std::cout << "..." << std::endl;
}
输出:
GrandParent: printMe!
...
GrandParent: printMe!
Parent: printMe!
...
GrandParent: printMe!
Parent: printMe!
Child: printMe!
...
但是,那么你必须处理静态方法和多重继承。