我有一个名为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,只是在重要的情况下。
答案 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),我们可以保存函数模板实例化。