[英]this pointer to base class constructor?
我想實現一個派生類,它也應該實現一個接口,它有一個基類可以調用的函數。 以下是一個警告,因為將this指針傳遞給基類構造函數是不安全的:
struct IInterface
{
void FuncToCall() = 0;
};
struct Base
{
Base(IInterface* inter) { m_inter = inter; }
void SomeFunc() { inter->FuncToCall(); }
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
Derived() : Base(this) {}
FuncToCall() {}
};
圍繞這個最好的方法是什么? 我需要提供接口作為基礎構造函數的參數,因為它並不總是作為接口的衍生類; 有時它可能是一個完全不同的類。
我可以在基類SetInterface(IInterface * inter)中添加一個函數,但我想避免這種情況。
你不應該從構造函數中發布this
,因為那時你的對象還沒有正確初始化。 但是,在這種實際情況下,它似乎是安全的,因為您只將它發布到基類,它只存儲它,並且直到稍后某個時候才會調用它,此時構造將完成。
但是,如果要刪除警告,可以使用靜態工廠方法:
struct Base
{
public:
Base() { }
void setInterface(IInterface* inter) { m_inter = inter; }
void SomeFunc() { inter->FuncToCall(); }
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
private:
Derived() : Base() {}
public:
static Derived* createInstance() {
Derived instance = new Derived();
instance->setInterface(instance);
return instance;
}
FuncToCall() {}
};
請注意, Derived
的構造函數是私有的,以確保僅通過createInstance
完成實例化。
您始終可以推遲接口取消引用:
struct IInterface
{
virtual ~IInterface();
virtual void FuncToCall() =0;
};
class Base { public: virtual ~Base(); void SomeFunc() { GetInterface().FuncToCall(); } private: virtual IInterface& GetInterface() =0; };
class Derived: public Base, public IInterface { public: private: virtual IInterface& GetInterface() { return *this; } virtual void FuncToCall(); };
您可以執行一組有限的操作(由標准保證),並指向尚未初始化的對象,並將其存儲以供進一步使用。 編譯器可能會發出警告,因為很容易在Base
濫用接收到的指針。
請注意,除了存儲之外,指針的大多數用法都是未定義的行為,但上面的代碼是正確的。
有趣的是,您可以稍后通過初始化來逃避它:
Derived::Derived(): Base()
{
this->setInter(this);
}
很好,因為所有屬性都已初始化。
這樣您就不必為了逃避警告而改變整個設計。
然而,除非setInter
不會做任何this
除了一些存儲,你可能訪問你沒有完全初始化(所以存儲對象hash
值可以是尷尬)。
怎么樣:
struct IInterface
{
void FuncToCall() = 0;
IInterface* me() { return this; }
};
...
struct Derived : IInterface, Base
{
Derived() : IInterface(), Base(me()) {}
FuncToCall() {}
};
在我們到達Base構造函數IInterface的那一點已經初始化了,所以對me()的調用是安全的,並且沒有警告
如何使用protected:
for IInterface* m_inter;
struct IInterface
{
virtual void FuncToCall() = 0;
};
struct Base
{
Base(IInterface* inter) { m_inter = inter; }
void SomeFunc() { m_inter->FuncToCall(); }
protected: // or `public:` since you are using `struct`
IInterface* m_inter;
};
struct Derived : Base, IInterface
{
//Derived() : Base(this) {} // not good to use `this` in the initialization list
Derived() : Base() { m_inter = static_cast<IInterface*>(this); }
FuncToCall() {}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.