C++ 继承基构造函数,但仍调用默认派生构造函数
C++ Inherit base constructor, but still call default derived constructor
我一直在为这个问题而苦苦挣扎:
目前我有这个代码:
class B {
public:
B(int, int, int, int);
[many other ctors]
};
class D : public B {
public:
using B::B;
[other methode]
};
现在我希望 D 管理一些指针,我需要独立于传递给构造函数的参数进行初始化。
我试过这个:
class B {
public:
B(int, int, int, int) {
[other stuff]
init();
}
[many other ctors]
virtual void init() {}
};
class D : public B {
public:
using B::B;
void init() {
mPointer = new Stuff(42);
}
private:
mPointer = nullptr;
};
但显然,如果你从 B::B(int,int,int,int,int) 调用虚拟方法,它会调用 B::init,而不是 D::init。
有没有一种很好的方法来完成这项工作,或者我需要用 D 重写所有 B 的 ctors?
谢谢!
不能从构造函数调用虚函数。这与对象的构造顺序有关:
struct E {
E() { std::cout << "E" << std::endl; }
int g = 7;
};
struct F : E {
B() { std::cout << "F" << g << std::endl; }
};
F f;
构造f
时,程序将输出EF7
。首先构造基类,因此在派生类中,可以调用方法并使用父类的成员。
实际上,通过上面的简单示例,您可以在构造函数中使用变量g
F
因为之前调用了父构造函数。否则它的格式不正确,因为E
的构造函数是设置g
7
这与您的问题有什么关系?
好吧,在基构造函数中,您正在调用一个虚函数。您希望在派生类中调度调用的虚函数。问题是,还没有派生类。
您会看到,首先构造类B
。目前还没有D
!由于尚不存在D
,因此无法执行虚拟调度来调用D
函数!因此,编译器将回退到当时可以选择的函数。在您的情况下,该函数B
初始化函数。
正如其他人所说,在构造函数中调用派生的虚函数并非易事,但这不是解决问题的唯一方法。
在您的特定情况下,我理解为您想要初始化继承类的成员但仍重用基类构造函数,您可以使用类内成员初始化。这有效:
#include <string>
#include <iostream>
class Base {
public:
Base(int, int, int) { std::cout << "Calling base constructor" << std::endl; }
};
class Derived : public Base {
public:
using Base::Base;
std::string member{"This is a member string"};
};
int main() {
Derived d(1, 2, 3);
std::cout << d.member << std::endl;
return 0;
}
正如你在这里看到的,使用 GCC 编译上面的代码(并且没有优化)确实会生成一个Derived
构造函数,它会调用Base
构造函数并初始化std::string
成员。
是的。虚拟方法从构造函数中非虚拟调用,因为在调用基类构造函数时尚未构造派生类。
这是最终调用纯虚函数的已知方法 - 只需调用一些从构造函数调用纯虚拟函数的中间函数(你不能直接从构造函数调用纯虚函数,编译器不允许你)。
若要解决您的问题,请声明您自己的构造函数并调用基类构造函数,然后进行特定的初始化,而不是继承构造函数。
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 减少复制构造函数调用
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 在 Google 测试中,我可以从构造函数调用 GetParam() 吗?
- C++ - 从另一个类构造函数调用类构造函数
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 是否可以从移动构造函数调用默认构造函数?
- 在模板生成器模式中分解重复的构造函数调用
- std::atexit 从全局对象的构造函数调用时的排序
- 对构造函数调用的约束
- 编译器错过了无效的构造函数调用,并调用不存在的(或私有的)默认构造函数
- 用构造函数调用填充向量
- 创建指针时是否没有构造函数调用
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- C++ 抽象类构造函数调用
- 为什么函数参数将带有参数的构造函数调用
- 为什么比“构造函数”调用更多的“解构器”调用
- 将对象传递给函数并不是导致构造函数调用