C++ 在派生类对象构造后调用虚函数
以下是一些示例代码:C++ 在派生类对象构造后调用虚函数,c++,constructor,polymorphism,C++,Constructor,Polymorphism,以下是一些示例代码: #include <iostream> class A { public: virtual void foo() { std::cout << "base" << std::endl; } A() { foo(); } }; class B : public A { int a; public: void foo() { std::cou
#include <iostream>
class A {
public:
virtual void foo() {
std::cout << "base" << std::endl;
}
A() {
foo();
}
};
class B : public A {
int a;
public:
void foo() {
std::cout << "derived" << std::endl;
}
B(int a) :
a(a) {}
};
int main() {
B o(1);
return 0;
}
#包括
甲级{
公众:
虚拟void foo(){
std::cout无法调用重写的foo()
从基类构造函数开始,无论您做什么。调用基类构造函数时,派生类对象尚未构造,因此您无法调用其任何方法或访问其任何成员。对于虚拟函数和常规函数也是如此。在基类构造函数中ode>此
指针指向基类,而不是派生类。无法调用重写的foo()
从基类构造函数开始,无论您做什么。调用基类构造函数时,派生类对象尚未构造,因此您无法调用其任何方法或访问其任何成员。对于虚拟函数和常规函数也是如此。在基类构造函数中ode>此指针指向基类,而不是派生类。一个潜在的解决方法是将构造委托给客户端必须调用的单独函数。然后让该函数在构造后调用foo:
class A {
public:
virtual void foo() {
std::cout << "base" << std::endl;
}
template<typename T, typename ... Args>
static T construct(Args ... args)
{
T newT{ args... };
newT.foo();
return std::move(newT);
}
protected:
A() {
//Construct A
}
};
class B : public A {
int a;
public:
void foo() {
std::cout << "derived" << std::endl;
}
B(int a) :
a(a) {}
};
int main()
{
B o = A::construct<B>(1);
A a = A::construct<A>();
return 0;
}
A类{
公众:
虚拟void foo(){
std::cout一个潜在的解决方法是将构造委托给客户端必须调用的单独函数。然后让该函数在构造后调用foo:
class A {
public:
virtual void foo() {
std::cout << "base" << std::endl;
}
template<typename T, typename ... Args>
static T construct(Args ... args)
{
T newT{ args... };
newT.foo();
return std::move(newT);
}
protected:
A() {
//Construct A
}
};
class B : public A {
int a;
public:
void foo() {
std::cout << "derived" << std::endl;
}
B(int a) :
a(a) {}
};
int main()
{
B o = A::construct<B>(1);
A a = A::construct<A>();
return 0;
}
A类{
公众:
虚拟void foo(){
std::cout To clear,您希望调用派生的foo()
重载,即使这不是示例程序中发生的情况?是的。如果重载会发生在我的代码中,那么我的问题是没有意义的。Oops,我的意思是重写,而不是重载。要明确,您希望派生的foo()
要调用的重载,即使在示例程序中不是这样的情况?是的。如果重载会发生在我的代码中,那么我的问题就没有意义了。哦,我的意思是重写,而不是重载。我不需要从构造函数调用它。我想在所有派生类对象构造(完整)之后调用它,但不需要在派生类中添加其他代码。@Omicrons,很抱歉,这是不可能的。@Omicrons这也非常令人困惑,您想从派生类调用函数而不向派生类添加额外代码吗?当然,从派生类调用任何函数的实现都会导致n额外代码?为什么不让派生类调用基类要调用的任何函数?我不需要从构造函数调用它。我想在所有派生类对象构造(完整)之后调用它,但不需要在派生类中添加其他代码。@Omicrons,很抱歉,这是不可能的。@Omicrons这也非常令人困惑,您想从派生类调用函数而不向派生类添加额外代码吗?当然,从派生类调用任何函数的实现都会导致n额外的代码?为什么不让派生类调用基类将要调用的任何函数?问题是,您仍然可以执行bo(1);
-因此需要程序员规范来使用创建者。但是如果您有足够的规范来使用创建者,为什么还要麻烦它呢?根据相同的规范,您可以简单地调用foo()在调用站点。@SergeyA Yup,这并不完美。您可以使子类构造函数也受到保护,但是您需要在所有子类中声明友元。在这种情况下,这可能是合理的。我仍然认为这是OP问题的合理解决方案。问题是您仍然可以执行BO(1)
-所以使用creator需要程序员的纪律。但是如果你有足够的纪律来使用creator,为什么还要麻烦它呢?根据同样的纪律,你可以简单地调用foo()在调用站点。@SergeyA Yup,这并不完美。您可以使子类构造函数也受到保护,但是您需要在所有子类中声明友元。在这种情况下,这可能是合理的。我仍然认为这是解决OP问题的合理方法。