簡體   English   中英

將派生自接口的類的實例添加到接口指針數組

[英]Adding an instance of a class derived from an interface to an array of interface pointer

我有一個名為IFoo的接口結構。

struct IFoo
{
    void someFunc();

    virtual ~IFoo()
    {
    }
};

我從接口派生了多個結構。 每個結構可以具有不同的構造函數。

struct FooA : IFoo
{
    FooA(int i1, int i2)
    {
    }

    void someFunc()
    {
    }

    ~FooA()
    {
    }
};

struct FooB : IFoo
{
    FooB(int i)
    {
    }

    void someFunc()
    {
    }

    ~FooB()
    {
    }
};

我有一個結構,該結構(將)包含一個指針數組(在示例中,為簡單起見,只有一個項目)。

struct FooContainer
{
    IFoo* fooItem;
};

FooContainer對派生實例一無所知。

我寫了下面的代碼,看起來很有效。

以這種方式將IFoo的指針設置為派生結構(例如FooA)的指針是否有效?

誰能告訴我這是個好主意嗎? 它看起來可以正常工作...但是我現在想知道我可能遇到的任何問題(內存問題等),而不是直接找到它們。 我知道我將需要添加缺少的方法...賦值運算符,復制構造函數等:)

struct FooContainer
{
    IFoo* fooItem; // this will be an array of ifoo pointers in actual code

    FooContainer()
        : fooItem(0)
    {
    }

    template <typename T>
    void setFoo(const T& foo)
    {
        delete fooItem;

        fooItem = new T(foo); // this will add the item to the array
    }

    ~FooContainer()
    {
        delete fooItem;
    }
};

被這樣稱呼:

FooContainer fooContainer = FooContainer();
fooContainer.setFoo(FooA(1, 1));

這不是C ++ 11,以防萬一。

是的,這就是您應該這樣做的方式。

盡管您可能希望someFuncvirtual

將IFoo的指針設置為派生結構(例如FooA)的指針是否有效?

是的,那是完全正確的事情。

當您擁有一個指向派生類型的指針,並將其分配給一個指向其基本類型之一的指針時,編譯器會根據需要自動調整該指針。 您對fooContainer.setFoo(FooA(1, 1))調用使編譯器實例化

void setFoo<FooA>(const FooA& foo)

因此,新的和分配成為

fooItem = new FooA(foo);

在這里, new FooA(foo)返回一個FooA* ,它會根據賦值運算符的要求隱式轉換為IFoo*

唯一要注意的事情(您已經做對了)是在基類中聲明(可能定義)虛擬析構函數。 這是必需的,因此,如果delete fooItem ,則會調用實際對象的析構函數(例如FooA::~FooA() )。

對於派生類,您無需定義空的析構函數。

“將IFoo的指針設置為派生結構(例如FooA)的指針是否有效?”

這是C ++中多態性的主要本質。 您可以將任何派生類指針傳遞給需要基類指針的函數。 當您通過該基本指針編譯器調用任何虛函數時,將為您調用適當的函數。

Is it valid to set a pointer of IFoo to a pointer of a derived struct (say, FooA)?

是的,這是完全有效的。 您可以將任何派生類指針分配給基類指針,前提是基類應包含虛擬析構函數。

virtual ~IFoo()
{
}

在FooContainer類中,您可以像這樣更改setFoo函數

struct FooContainer
{
    IFoo* fooItem; // this will be an array of ifoo pointers in actual code

    FooContainer() : fooItem(0)
    {
    }

    void setFoo(IFoo *obj)
    {
        delete fooItem;

        fooItem = obj;
    }

    ~FooContainer()
    {
        delete fooItem;
    }

};

現在,在調用者代碼中,您必須像這樣更改它

FooContainer fooContainer = FooContainer();
fooContainer.setFoo(new FooA(1, 1));

這樣,我們可以保存FooA類的一個臨時實例的創建/銷毀。 同樣對於每個類(例如FooA,FooB),我們可以保存功能模板實例化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM