从构造函数的主体调用超类构造函数
Calling superclass constructor from constructor's body
我想创建一个类构造函数,它只会在特定条件下调用它的超类构造函数。我目前的实现如下所示。
class MyClass : public OtherClass
{
public:
template<typename... Args>
MyClass(bool condition, Args&&... args)
{
if(condition)
{
*(OtherClass*)this = OtherClass(args...);
}
else
{
// Unrelated stuff
}
}
};
我不能在这里使用MyClass(...) : OtherClass(...) {}
语法,因为不应该每次都调用超类的构造函数。
有没有办法直接调用超类构造函数而不是调用移动构造函数(如我的示例所示)。
可以为基类和派生类创建 2 个不同的构造函数。
派生类的构造函数调用基类的相应构造函数。
派生类中的静态方法基于传递的参数创建实例。
像这样:
class OtherClass
{
public:
OtherClass()
{
...
}
OtherClass(Args&... args)
{
...
}
} // class OtherClass
class MyClass: public OtherClass
{
private:
MyClass(): OtherClass()
{
...
}
MyClass(Args&... args): OtherClass(args)
{
...
}
public:
static MyClass* createInstance(bool condition,
Args&&... args)
{
if (condition)
return (new MyClass());
else
return (new MyClass(args));
}
} // class MyClass
解决方案是不在构造函数中执行此操作,而是在帮助函数中执行此操作。 例如:
class BaseClass {
BaseClass() {}
BaseClass(int x) {setX(x);}
void setX(int x) {
//thing
}
}
class Derived : BaseClass {
Derived(int x) {
if (x>10) setX(x);
}
}
您可以通过以下方式重载构造函数来实现标记调度:
struct PassArgs {};
struct DoNotPassArgs {};
class MyClass: public OtherClass {
public:
template<typename... Args>
MyClass(PassArgs, Args&&... args) : OtherClass(args...) {}
template<typename... Args>
MyClass(DoNotPassArgs, Args&&...) : OtherClass() {}
};
罗伯特·科克的上述回答并不完全正确。他从派生类构造函数的初始化列表中调用基类(晚餐类)构造函数,但没有条件。但根据您的问题can we call a base class constructor based on a CONDITION from the BODY of derived class constructor?
.答案是否定的,我们不能。根据面向对象的原则,基类构造函数必须首先调用和初始化。在 Robert Kock 的上述答案中,基类构造函数是在控件进入主体内部之前从驱动器类构造函数的初始化列表中调用的,没有任何条件。在初始化列表中,您甚至不能放置任何条件。因此,不可能从派生类构造函数的主体调用基于类构造函数。这就是我们在类中引入另一个称为 init() 的方法的原因。现在,以下示例可以完全满足您的要求。在此示例中,您必须在基类中添加一个默认构造函数,以便首先调用此默认构造函数,但在该默认构造函数中,您不会执行任何操作。
现在看下面的例子:-
#include<iostream>
class B
{
private:
int x;
int y;
public:
B(){std::cout<<"I am B's default constructor"<<std::endl;}//Default constructor not doing anything
void init(int x)
{
std::cout<<"Based init with param x"<<std::endl;
this->x = x; //this method initializing only one member
y = 0;// just initialized with default value 0
}
void init(int x,int y)
{
std::cout<<"Based init with param x and y"<<std::endl;
this->x = x; // here we initializing all the members
this->y = y;
}
void print()
{
std::cout<<"x ="<<x<<std::endl;
std::cout<<"y ="<<y<<std::endl;
}
};
class D : public B
{
public:
D(int i)
{
std::cout<<"I am D's constructor"<<std::endl;
if( i == 1 )
B::init(3);
else
B::init(4, 5);
}
};
int main()
{
std::cout<<"First Example"<<std::endl;
D *d = new D(1);
d->print();
std::cout<<"Now second Example"<<std::endl;
D *d1 = new D(2);
d1->print();
return 0;
}
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 参数包构造函数在类模板中隐藏用户定义的转换
- 具有已删除移动和复制构造函数的类的就地构造
- 创建一个没有复制构造函数的类的 std::vector 的 std::vector
- C++构造函数和类?
- 在 C++ 中,默认情况下构造函数为类的数据成员提供的值是多少?
- 如何在其他类中使用参数化构造函数制作类的对象?
- 具有值包装器的可变参数模板构造函数的类构造函数优先级
- 如何使用私有构造函数对类进行单元测试?
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 从作为模板参数传递给构造函数的类继承,或者从它们继承
- 继承的构造函数忽略类内初始化
- 模板和隐式构造函数的类定义之外的友元声明
- 具有字符串文本构造函数的类不适用于 const 引用初始化
- C++ - 从另一个类构造函数调用类构造函数
- 定义结构中没有默认构造函数的类
- 我可以将 std::move 与不提供 move 构造函数的类一起使用吗?
- 是否可以默认初始化具有已删除默认构造函数的类类型
- C++具有移动和复制构造函数的类中的代码重复
- 没有默认构造函数的类对象的值初始化