将对成员的引用传递给基类的构造函数
Passing reference to member to constructor of base class
我创建了一个依赖项注入,其中a依赖于IB,B1实现IB。对于一个非常特殊的情况,我想创建一个不会公开依赖项注入的类C:a。我想要:
- C来构造依赖项并将其传递给它的基类A,从而优雅地处理依赖项的生存期
- C可以轻松地向用户公开A的公共方法
class IB
{
public:
virtual void InterfaceCall() = 0;
/* ... */
}
class B1 : IB
{
public:
void IntefaceCall();
/* ... */
}
class A
{
public:
A(IB& ib);
}
// for a specific case I would like to use class A and all it's logic and public methods, but remove dependency injection
class C : A
{
B1 b1;
public:
C()
: A(b1)
, b1() // the order of initialization list is determined by standard
{}
}
这可能吗?或者我需要放弃对C的一个要求吗?
如果A
构造函数实际上没有使用引用访问任何成员,我相信这是格式良好的
编辑:A
的析构函数也不能使用引用的任何成员,因为值将按相反的顺序析构函数(首先是b1
,然后是继承的A
(。
在不知道A
构造函数和/或析构函数如何通过控制初始化顺序来使用引用的情况下,您可以确保这是一个良好的格式。您可以通过在从A
继承之前继承另一个提供b1
成员的类型来实现这一点。
以下是我们将继承的类型:
// C++03 version
template <typename T, typename = void>
struct member
{
T value;
};
// C++11 version
template <typename T, typename = void>
struct member
{
T value;
template <typename... Args>
member(Args && ...a) : value{std::forward<Args>(a)...} { }
};
然后,在继承A
:之前,我们将让C
私下继承它
class IB
{
public:
virtual void InterfaceCall() = 0;
};
class B1 : public IB
{
public:
B1() { std::cout << "constructed B1 " << static_cast<void *>(this) << 'n'; }
virtual void InterfaceCall() { }
};
class A
{
public:
A(IB & ib) { std::cout << "constructed A with B1 " << static_cast<void *>(&ib) << 'n'; }
};
class C : private member<B1>, public A
{
// For convenience, if you need to use the B1 object in C. If not, you
// can omit this reference.
B1 & b1;
public:
C() :
member<B1>(), // Implied
A(member<B1>::value),
b1(member<B1>::value) { }
};
证明初始化顺序正确的示例输出:
constructed B1 0x7ffe691b9710
constructed A with B1 0x7ffe691b9710
(演示(
请注意,member
模板的第二个参数是一个标记,如果需要,它将允许您使用此技术来控制同一类型的多个成员的初始化顺序。例如,class foo : member<B1, TagA>, member<B1, TagB>
。
相关文章:
- C++17 使用驱动类常量作为基类构造函数的参数来初始化基类构造函数
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- 在成员构造函数之后调用基类构造函数
- 如何在将原始指针移动到基类构造函数之前从unique_ptr中提取原始指针
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- 如何在 C++ 中将参数传递给基类构造函数
- 将数据成员的指针传递给基类构造函数是否安全?
- 使用基类构造函数初始化儿童类
- 使用基类构造函数的子类构造函数的大纲定义
- MSVC 无法识别继承模板类的模板类的"直接"基类构造函数
- 子类的构造函数后跟冒号后的基类构造函数是什么意思?
- 是否可以使用基类构造函数通过派生类将值初始化为基类私有成员?
- 当派生类无法轻易将参数传递到基类时,如何调用基类构造函数
- 是否可以在运行时切换到不同的基类构造函数?
- 对基类构造函数的未定义引用
- 如何为基类构造函数中的每个子类执行特定任务
- 将类传递到基类构造函数的模板参数中?
- 如何在基类构造函数中使用派生类成员
- (为什么)纯虚拟派生类中是否需要虚拟基类构造函数调用?
- 使用相同的参数调用基类C++构造函数