![](/img/trans.png)
[英]C++ class construction by member initializer list with pointer to member address
[英]In C++, initialize a class member with 'this' pointer during construction
我想创建一个与某个父子关系中的另一个类相关联的类。 为此,“child”类需要引用它的父级。
例如:
template <typename T>
class TEvent {
private: T* Owner;
public: TEvent(T* parent) : Owner(parent) {}
};
class Foo {
private: TEvent<Foo> Froozle; // see below
};
现在的问题是我不能直接初始化Froozle
实例,也不能使用Foo构造函数的instanciation列表,因为那里不允许this
引用。 除了添加另一个方法setParent(T*)
(我不太喜欢因为它意味着我必须让TEvent<>
实例处于无效状态),有没有办法实现这一点?
可以在初始化列表中使用this
,只要它不用于访问可能尚未初始化的任何成员。
从标准的12.6.2 / 7“初始化基础和成员”(强调我的):
mem-initializer的表达式列表中的名称在为其指定mem-initializer的构造函数的范围内进行计算。
[例:
class X { int a; int b; int i; int j; public: const int& r; X(int i): r(a), b(i), i(i), j(this->i) {} };
初始化
X::r
指X::a
,初始化X::b
与构造参数的值i
,初始化X::i
用构造参数的值i
,并初始化X::j
与值X::i
; 每次创建class X
的对象时都会发生这种情况。 ][注意:因为mem-initializer是在构造函数的范围内计算的,所以
this
指针可以在mem-initializer的表达式列表中用于引用正在初始化的对象。 ]
这应该有效; 事实上,
template<class T>
class Child {
private:
T *parent;
public:
Child(T *parent) : parent(parent) {}
};
class Parent {
private:
Child<Parent> child;
public:
Parent() : child(this) {}
};
使用g ++ 4.4.5和clang ++ 2.8编译好。
什么失败了?
除非你将警告级别设置为4(或者类似,我假设是Visual Studio)并且已经启用“将警告视为错误”,否则我认为它没有失败。
基本上,这个警告是A Good Thing,因为当它指向的内容尚未构建时,它不会让你意外地使用 this
指针。
但是,当你知道,无论你在做什么, this
在初始化列表被传递,由此引起的警告和错误将是烦人。
您可以通过修饰构造函数来解除它(再次,假设Visual Studio)(除非它在类声明中定义 - 然后您必须装饰所有类):
// warning C4355: 'this' : used in base member initializer list
#pragma warning (push)
#pragma warning (disable : 4355)
some_class::some_class()
: ...
{
}
#pragma warning (pop)
如果您要抑制警告,请执行以下操作:
class Foo
{
public:
Foo() :
Froozle(get_this())
{}
private:
Foo* get_this()
{
return this;
}
TEvent<Foo> Froozle; // see below
};
间接足以阻止它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.