簡體   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