繁体   English   中英

在C ++中,在构造期间使用“this”指针初始化类成员

[英]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::rX::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM