下面是一个C++类:
// Header-File
class A
{
public:
A();
private:
B m_B;
C m_C;
};
// cpp-File
A::A()
: m_B(1)
{
m_B.doSomething();
m_B.doMore();
m_C = C(m_B.getSomeValue());
}
我现在想避免class A
调用C m_C
的any构造函数。因为在A::A()
的最后一行,我无论如何都要自己初始化m_C
,因为我需要首先准备m_B
。我可以为class B
提供一个空的默认构造函数。但这不是重点。
我已经尝试将m_C(NULL)
添加到A::A()
的初始化列表中。有时它工作,有时它说没有构造函数将NULL
作为参数。
那么,如何让m_C
保持未初始化状态呢?我知道使用指针时,m_C(NULL)
方式可以工作。我不想使用new
动态分配它。
任何想法都是赞赏的。
9条答案
按热度按时间dy1byipe1#
如何使用本QA中描述的技术?
Prevent calls to default constructor for an array inside class
或者,您也可以考虑使用
union
。AFAIK,unions will be initialized only with first named member's constructor.比如说
根据QA中提到的标准,
c
将被零初始化,并且其构造函数不会被调用。ovfsdjhp2#
你不能
当进入construcotr代码块时,所有成员变量都被完全构造。这意味着必须调用这些构造函数。
但是你可以绕过这个限制。
u5i3ibmn3#
我看不出有什么好办法能达到你的目的。这必须是一个解决方法:
请确保
m_B.doSomething()
、m_B.doMore()
和m_B.getSomeValue()
不接触m_C
(直接或间接)。正如@Tobias正确提到的,这个解决方案取决于初始化的顺序。您需要确保
m_B
和m_C
的定义按此顺序。根据@Loki的想法更新了代码。
jgzswidk4#
你所要求的是被禁止的--这是正确的。这样可以确保每个成员都被正确初始化。不要试图绕过它-试着构建你的类,让它们与它一起工作。
想法:
jjhzyzn05#
只需使用逗号表达式:
显然,正如其他人所解释的那样,
m_B
最好在m_C
之前声明,否则m_B.doSomething()
会调用未定义的行为。bqucvtff6#
指针听起来像是唯一干净的解决方案。我看到的唯一其他解决方案是为C设置一个默认的构造函数,它什么也不做,并在C中设置一个初始化方法,稍后您自己调用。
int n.getSomeValue();
1mrurvl17#
最简单的是存储指向
B
和C
的指针。这些可以初始化为0,省略任何构造。注意不要在A
的析构函数中取消引用空指针并将其删除(或使用std::unique_ptr
/boost::scoped_ptr
)。但是为什么不先初始化
m_B
(通过适当的构造函数调用,而不是在A::A()
中),然后使用初始化的B
示例来初始化m_C
呢?这将要求一个小的重写,但我打赌这将是值得的代码清理。zi8p0yeb8#
如果出于代码混乱/异常安全的原因,不想使用
new
动态分配它,可以使用std::unique_ptr
或std::auto_ptr
来解决这个问题。避免
new
的一个解决方案是编辑C
,使其具有两步初始化过程。然后,构造函数将构造一个“僵尸”对象,您必须在该m_C
示例上调用Initialize
方法来完成初始化。这与您发现的现有情况类似,您可以将NULL
传递给构造函数,然后返回初始化对象。编辑:
我之前就想到了这个(尽管它看起来很像其他人的解决方案)。但我必须得到一些确认,这不会打破之前,我添加了这个解决方案- C++可以是相当棘手的,我不经常使用它:)
这比我的其他建议更简洁,并且不需要你去搞砸除了
A
之外的任何实现。简单地使用静态方法作为初始化的中间人:
请注意,这意味着您根本不能允许
m_B
依赖于A
或C
的示例,而这个答案顶部的解决方案可能允许您将A
或m_C
传递到m_B
的方法中。6qfn3psc9#
这里我们有构建块:
如果你想为B创建一个新的构造,可以考虑创建一个派生类:
现在使用从B派生的类B1:
然后:
输出: