初始化引用 - 警告 C4355: 'this' : used in base member initializer list
Posted
技术标签:
【中文标题】初始化引用 - 警告 C4355: \'this\' : used in base member initializer list【英文标题】:Initialize a reference - warning C4355: 'this' : used in base member initializer list初始化引用 - 警告 C4355: 'this' : used in base member initializer list 【发布时间】:2010-08-18 06:24:06 【问题描述】:class A;
class B
public:
B(A& a) : a(a)
private:
A& a;
;
/* Method 1 */
/* warning C4355: 'this' : used in base member initializer list */
/*
class A
public:
A() : b(*this)
private:
B b;
;
*/
/* Method 2 */
/* But I need to manually perform memory dellocation. */
class A
public:
A() b = new B(*this);
~A() delete b;
private:
B* b;
;
int main()
目前,当我尝试在 B 中初始化引用时,我使用的是方法 1。但是,方法 1 会标记我警告,这是可以理解的。
因此,我必须使用方法 2,即使用动态内存分配。
有没有更好的方法我可以使用,而不需要手动分配/释放内存(好的。我知道智能指针)?
我更喜欢方法 1,只是我对警告不满意。
【问题讨论】:
【参考方案1】:注意这是一个警告(所以它是危险的而不是非法的)。
编译器担心的是您正在传递一个指向尚未完全初始化的对象的指针。因此,如果在 B 类构造函数中使用该指针,则您处于未定义的行为中。
因此,如果您确实使用它,您唯一能做的就是将指针分配给成员变量(引用或指针)。 但请注意要小心分配给变量,因为您可能会调用隐式强制转换(我不确定这是否真的是一个问题,但在对象完全形成之前 RTTI 不可用)。
你想通过存储引用来实现什么?
【讨论】:
【参考方案2】:这样做是有效的。
但是,您必须确保(我的意思是您自己,编译器无法做到这一点)this
在对象完全构造之前不用于调用虚函数。
【讨论】:
【参考方案3】:根据您正在做的事情,一种方法可能是将A
中B
需要的部分分解出来,而不是让A
从该部分继承。
struct bar_base; // interface foo wants
struct foo
foo(bar_base& pX) :
mX(pX)
bar_base& mX;
;
struct bar_base
/* whatever else */
protected:
bar_base& get_base(void)
// getting `this` went here; safe because bar_base is initialized
return *this;
;
struct bar : bar_base
bar(void) :
// bar_base is already initialized, so:
mX(get_base())
foo mX;
;
显然,这取决于您在做什么。这样可以确保您永远不会遇到未定义的行为。
但实际上,这只是警告。如果您承诺永远不会在 B 的构造函数中使用 this
,那么您很好,并且可以通过这种方式使警告静音:
struct bar;
struct foo
foo(bar& pX) :
mX(pX)
bar& mX;
;
struct bar
bar(void) :
mX(self())
foo mX;
private:
bar& self(void)
// fools the warning
return *this;
;
不过,请确保您知道自己在做什么。 (或许可以重新设计?)
【讨论】:
【参考方案4】:好吧,避免警告的一种明显方法是让 B 存储指向 A 的指针,然后您不必在 B 的构造函数/A 的初始化器列表中对其进行初始化,并且可以等到 A 的构造函数的主体正在执行中……
【讨论】:
【参考方案5】:认真对待这个警告。您的 this
对象尚未完全构造,并且传递是不安全的(如果您不小心调用了 this
上的函数,则调用 UB)。此外,还有其他用于内存管理的技术。尝试查找分配器的 STL 设计。
您也可以使用 RAII/智能指针来达到相同的效果。
或者,您是否正在尝试编写某种垃圾收集器/内存分析器?
【讨论】:
以上是关于初始化引用 - 警告 C4355: 'this' : used in base member initializer list的主要内容,如果未能解决你的问题,请参考以下文章