![](/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.