在初始化列表之外手动调用基类的构造函数 [英] Manually calling constructor of base class outside initialization list
问题描述
我有一个 Derived
类,其构造函数必须填充作为参数传递的 struct
的字段到 Base
类的构造函数。我希望能够命名要填充的结构的字段,以使我的代码适应未来(例如:抵抗 MyStruct $ c $成员的添加和/或重新排序) c>)。
I have a Derived
class whose constructor has to populate the fields of a struct
that is passed as an argument to the constructor of the Base
class. I want to be able to name the fields of the struct that I am populating, to keep my code future-proof (i.e.: resistant to addition and/or reordering of the members of MyStruct
).
请注意, struct MyStruct
具有默认值,因此无法直接在其中使用命名字段进行初始化初始化列表(例如: Base({。a = a,.b = b})
不起作用)。另外,就我而言, Base
的副本构造函数也被删除。另外,我正在使用C ++ 11。
Note that struct MyStruct
has default values, so it cannot be initialised with named fields directly in the initialization list (e.g.: Base({.a = a, .b = b})
does not work). Also, in my case, Base
's copy constructor is deleted. Also, I am using C++ 11.
我想到的解决方案使用 placement new
运算符手动调用 Base
类的构造函数在 this
指向的内存上。为此,我还必须在 Base
类中添加受保护的
默认构造函数。这种方法是否有任何弊端和/或有人可以建议一种更好的方法?
The solution I came up with uses the placement new
operator to manually call the constructor of the Base
class on the memory pointed to by this
. To achieve this I also had to add a protected
default constructor to my Base
class. Are there any possible downsides to this approach and/or could anyone suggest a better method?
#include <iostream>
struct MyStruct
{
int a = 0;
int b = 1;
};
class Base
{
public:
Base(MyStruct str){
std::cout << "a: " << str.a << ", b: " << str.b << "\n";
}
Base(Base&&) = delete; // no copy constructor
protected:
Base(){ // dummy, does exactly nothing.
// it only exists to be called by
// the derived class's constructor
}
private:
int amember;
};
class Derived : public Base
{
public:
Derived(int a, int b)
{
MyStruct str;
str.a = a;
str.b = b;
new (this) Base(str);
}
private:
int anothermember;
};
int main()
{
MyStruct str;
str.a = 10;
str.b = 20;
Base b(str);
Derived d(10, 20);
return 0;
}
编辑:添加提及不能复制Base,明确指出 Base :: Base()
完全不执行任何操作。
edit: added mention that Base cannot be copied, made explicit that Base::Base()
does exactly nothing.
推荐答案
使用辅助函数代替例如
class Derived : public Base
{
public:
Derived(int a, int b) : Base(make_mystruct(a, b)), anothermember(some_value) {}
private:
int anothermember;
static MyStruct make_mystruct(int a, int b) { return MyStruct(a, b); }
};
这篇关于在初始化列表之外手动调用基类的构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!