在容器中存储多个继承对象
Storing multiple-inheritance objects in container
我使用的一个库有很多类型,所有类型都源自相同的两个接口:
class Huey : public IDuck, public ICartoonCharacter
{
...
};
class Dewey : public IDuck, public ICartoonCharacter
{
...
};
class Louie : public IDuck, public ICartoonCharacter
{
...
};
我希望将上述所有类型的对象存储在一个包装类中,并将该包装类的对象粘贴在一个容器中。当然,我应该能够从包装器类中调用属于这两个接口的方法。
我有什么选择?我能想到
- 将
IDuck *
存储在我的包装器中,并将dynamic_cast-ing存储到ICartoonCharacter
,或者 - 使用类似
boost::any
的东西,同时使我的包装器成为类模板,并使用几个static_asserts
来确保模板参数继承自IDuck
和ICartoonCharacter
但这两种选择都没有特别的吸引力。有什么想法吗?
两个接口,多个继承组合成一个容器?是一个相关的问题,但詹姆斯·坎泽的回答对我不起作用,因为我无法更改这三个课程。
编辑:不要经常使用多重继承,忘记了语法。现在从两个接口继承public
ly。
编辑:现在使用dynamic_cast而不是static_cast(这不起作用)。
编辑:我发现Mike Seymour和Matthieu M的回答都很有希望。一旦我把它们全部编码好,我就会接受它们的一个答案。谢谢
一个简单的选项是在包装器中存储两个指针:
struct CartoonDuckWrapper {
IDuck * duck;
ICartoonCharacter * toon;
template <class CartoonDuck>
CartoonDuckWrapper(CartoonDuck & cd) : duck(&cd), toon(&cd) {}
};
没有特别需要使用static_assert
来检查CartoonDuck
是否从两个基类继承,尽管这可能比简单地让指针转换失败提供更好的诊断。
如果基类是多态的(作为接口,它们可能是多态的),那么可以通过使用dynamic_cast
将一个指针转换为另一个指针来节省一个指针的空间,以换取运行时成本。static_cast
不能用于基类之间的这种"交叉转换"。
作为编程中的所有问题,您可以通过增加一个间接级别来解决它。
class ICartoonDuck: public IDuck, public ICartoonCharacter {};
template <typename T>
class CartoonDuck: public ICartoonDuck {
public:
explicit CartoonDuck(T t): _t(std::move(t)) {}
// IDuck interface
virtual void foo() override { t.foo(); }
// ICartoonCharacter interface
virtual void bar() override { t.bar(); }
private:
T _t; // or any ownership scheme that makes sense
}; // class CartoonDuck
template <typename T>
CartoonDuck<T> makeCartoonDuck(T t) { return CartoonDuck(std::move(t)); }
template <typename T, typename... Args>
std::unique_ptr<CartoonDuck<T>> makeUniqueCartoonDuck(Args&&...) {
return std::unique_ptr<CartoonDuck<T>>(new T(std::forward<Args>()...);
}
现在,您可以愉快地将std::unique_ptr<ICartoonDuck>
存储在您的容器中。
这可以用作:
std::vector<std::unique_ptr<ICartoonDuck>> cartoonDucks;
cartoonDucks.push_back(makeUniqueCartoonDuck<Huey>());
cartoonDucks.push_back(makeUniqueCartoonDuck<Dewey>());
cartoonDucks.push_back(makeUniqueCartoonDuck<Louie>());
for (std::unique_ptr<ICartoonDuck> const& cd: cartoonDucks) {
cd->foo();
cd->bar();
}
创建一个中间类:
class ILuckyDuck: public IDuck, ICartoonCharacter //...
带有:
class Huey : public ILuckyDuck //...
等,并存储:
std::vector<std:shared_ptr<ILuckyDuck>> donald;
相关文章:
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 使用智能指针附加的继承对象的深层复制
- 虚拟类继承对象大小问题
- 基对象和继承对象,用于将标准变量包装在C++中
- 为什么私有继承对象允许成员函数将派生的*转换为基*,而外部不能
- 是否有一种方法可以专门使用继承对象的一般方法
- 如何将接口对象强制转换为特定的继承对象
- MFC C++ 无法在动态创建的 CButton 继承对象上设置映像
- 在容器中存储多个继承对象
- QObject基类到继承对象的C++类型转换
- C++ 中的继承对象和属性丢失
- 继承对象列表 - C++
- 静态分配继承对象的数组
- 正确实例化双重继承对象
- 我是否需要使用继承对象(相对于基对象)覆盖我的虚函数?
- c++继承.对象调用超类方法而不是自己的方法
- 基对象和继承对象的向量
- 将多继承对象转换为void*或从void*转换为多继承对象
- 如何在c++中表示继承对象的树?
- 继承对象上指针算术的安全性