将从接口派生的类的实例添加到接口指针数组

时间:2014-10-30 12:58:20

标签: c++ pointers derived-class

我有一个名为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,只是在重要的情况下。

4 个答案:

答案 0 :(得分:1)

是的,这就是你应该这样做的。

虽然您可能希望someFunc成为virtual

答案 1 :(得分:1)

  

将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())。

对于派生类,您不需要定义空的析构函数。

答案 2 :(得分:0)

&#34;将IFoo的指针设置为派生结构的指针(例如,FooA)是否有效?&#34;

这是C ++中多态的主要本质。您可以将任何派生类指针传递给期望基类指针的函数。当你通过该基指针调用任何虚函数时,编译器会为你调用适当的函数。

答案 3 :(得分:0)

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),我们可以保存函数模板实例化。