C++ 从基类构造函数调用派生类的成员函数
如果我有C++ 从基类构造函数调用派生类的成员函数,c++,inheritance,C++,Inheritance,如果我有 struct C { C() { init(); }; void init() { cout << "C" << endl; }; }; struct D : public C { D() : C() { }; void init() { cout << "D" << endl; } }; D(); struct C{ C(){init();}; void init(){cout您只能从C构造函数中删除ini
struct C {
C() { init(); };
void init() { cout << "C" << endl; };
};
struct D : public C {
D() : C() { };
void init() { cout << "D" << endl; }
};
D();
struct C{
C(){init();};
void init(){cout您只能从C构造函数中删除init()
,以不打印“C”。
要同时打印“D”,请在D()
构造函数中添加init()
如果在某些情况下,您需要打印“C”或“D”,而在某些情况下,您不需要这样做
struct C {
C() { };
void init() { cout << "C" << endl; };
};
struct D : public C {
D() : C()
{
if(some condition)
C::init();
if(some condition)
init();
};
void init() { cout << "D" << endl; }
};
D();
struct C{
C(){};
void init(){cout
为什么要打印“C”
C::init()
未声明为virtual
,因此D
无法重写它。但是,即使C::init()
声明为virtual
,在C
的构造函数内部调用init
)时仍不会调用D::init()
C++在派生类之前构造基类(并且在基类之前分解派生类)。因此C
的构造函数在D
被构造之前运行(而C
的析构函数在D
被分解之后运行).正在构造/破坏的对象的VMT根本不指向D
的方法表当C
正在构造/破坏时,它指向C
的方法表
如何改变这种行为(并获得“D”)
无法从基类构造函数/析构函数内部调用派生虚拟方法。在这些阶段,VMT不包含指向派生类方法表的指针。这里有一个非常基本的问题:您希望在一个尚不存在的对象上调用派生类的成员函数
请记住,对象是通过先构造基本子对象,然后再构造派生对象来构造的。因此,即使您成功地应用了“聪明的”实际上调用派生类'init
函数的技巧,一旦该函数试图访问派生对象的任何数据成员,就会造成任意损坏。另一方面,只要不依赖构造函数尚未建立的任何不变量,就可以只访问基对象。因此或者,如果您不需要访问派生对象的数据,您可以使init
函数static
并将其传递给基类对象的引用
也许这正接近你想要做的
#include <iostream>
struct Base
{
Base(void (*fp)(Base&) = Base::init) { fp(*this); }
static void init(Base&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Derived : Base
{
Derived() : Base(Derived::init) { }
static void init(Base&) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
int
main()
{
Base b {};
std::cout << std::endl;
Derived d {};
}
在这里,基类构造函数采用一个函数指针,指向引用base
对象的初始值设定函数。该函数默认为base::init
,但派生类可以替换它。但是,请注意,在这种设计中,base
类构造函数可能无法安全地假定实际上,Base::init
的ct已经发生了。不过,作为一种扩展机制(如果Base::init
什么都不做或者是一次性的),它是很好的
<>但是我怀疑你是否需要使用这类机器。如果你想做的事情——这应该是正常的情况——首先初始化基础对象,然后是派生对象,如果你简单地调用来自各个构造函数的函数,C++将已经做正确的事情。
struct Base
{
Base() { this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Derived : Base
{
Derived() { this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
// main() as above ...
如果我们只想调用最派生的类'init
函数,我们可以简单地告诉基类不要运行自己的类
struct Base
{
Base(const bool initialize = true) { if (initialize) this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
struct Derived : Base
{
Derived() : Base(false) { this->init(); }
void init() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
// main() as above ...
即使init
是virtual
(我假设这是您想要实现的),从构造函数中调用virtual
函数也不是一个很好的主意这是一个公然反对多态性的案例。@DanielKamilKozar该类不是多态性的(没有任何虚拟函数)@MattMcNabb:当然。但是,看到OP的代码和预期结果,有理由认为使用多态性是他的意图之一。