在Java荒野中度过了太多时间后,我对C ++有点新鲜。
假设我有数据类A和B以及容器类,我将其称为Container:
class A
{
public:
virtual void foo()
{
cout << "I am an A" << endl;
}
};
class B : public A
{
public:
void foo()
{
cout << "I am a B" << endl;
}
};
template <class T> class Container
{
public:
T *_t;
Container(T *t)
{
_t = t;
}
};
我希望看起来像
的Java等价物B b = new B();
Container<? extends A> aContainer = new Container<B>(b);
如何在C ++中完成?这甚至是规范的吗?
以下代码给出了编译错误:
B *b = new B();
Container<A> *aContainer = new aContainer<B>(b);
到目前为止,谷歌一直没有帮助找到“?extends”的等价物。
==编辑==
解决方案是重写我的代码,以便不需要“?extends”,正如Isaac Drachman在下面描述的那样。
答案 0 :(得分:0)
如果您正在使用C ++ 11(或者可能是boost),那么如果A是B的基类,则可以使用包含(value =)true的std::is_base_of<A,B>
。
无论如何,你可以这样做:
template<class T>
class container {
void append(T* what);
}
考虑container<base>
如果你尝试做append(derived)
它没关系,因为指向派生的指针可以转换为基指针。
然而,这可以让你有一个任何列表。
如果你想控制它,比如Java中的“extends”;
static_assert(!std::is_base_of<base,T>::value,"You must derive from base");
坚持到某个地方并得到一个很好的错误信息“你必须从基地派生”
使用模板无法指定“T extends B”,因为模板系统复杂且更高级(能够执行更多操作),因此如果您指定具有相同方法名称的类型,则可以通过更改工作,或者您如果您错过了一个似乎没有告诉您错过方法名称的方法名称,则可能会出现可怕的错误。
答案 1 :(得分:-1)
您对A,B和Container类的声明是有效的,并且可以用于此目的。以下语法导致错误。
B *b = new B();
Container<A> *aContainer = new aContainer<B>(b);
首先,当对new
的类使用构造函数时,需要使用类名(如Java中),而不是对象。至于继承方面,您的容器被声明为Container<A>
,因此无法构造为Container<B>
,即使B继承自A。使用Container<A>
类型和构造函数为您的{{1}对象将允许您包含A对象或B对象,这是我认为您正在尝试做的事情。因此,您的代码应如下所示:
aContainer
编译并且应该对你有用。随意解释这是否适合您的想法。希望它有所帮助!