Polymorphism, why can't I do this?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class BaseA
{
}
class B : public BaseA
{
}
template <class T>
class C : public vector<T>
{
}
void someFunction (void)
{
C myClass;
// I can't seem to do this...is it not possible?
vector<BaseA> converted = ((vector<BaseA>) myClass);
} |
请参阅代码中的注释,了解我要做的事情。
- 了解协方差。
- 首先,没有一门课
- @这里的肉酱不是什么问题。
- @马丁霍夫南德斯:为什么不呢?看起来他想把一个vector转换成一个vector。
- list与list没有(继承)关系,不管a和b之间(继承)关系如何。
- @因为vector持有副本而被冻结。这种转换没有任何错误,除了它碰巧没有在std::vector中定义,而且可能发生切片。
- 我懂了。这就是为什么我通常不回答C++问题的原因。(我是一个小伙子)
- 快乐第十二万C++问题。
即使b是a,b的向量也不是a的向量(我假设a和basea混合在一起)。
尝试
1
| vector<A> converted(myClass.begin(), myClass.end()); |
这可能是你想要表达的。
(从向量继承btw通常是个坏主意,它不是为这个而设计的。)
- 这一点很重要。从任何STL容器继承不是一个好主意,因为它们没有虚拟析构函数。如果必须,请将容器用作成员。
- 您提出的解决方案在功能上是有用的,但它不会改变所需的行为,因为现在转换的是MyClass的一个浅拷贝,而不是对同一个向量的引用?
- @阿兰在这里,埃多克斯1〔2〕保存着埃多克斯1〔3〕中物体的深度复制品。在原版中,如果它起作用,converted将保存myClass中对象的深度副本。在已发布的代码中没有引用。
- 好吧,我们不允许这种行为(因为明显的原因)。如果在分析数组时忽略了根据需要强制转换迭代器,这是最接近的方法。
- 我懂了。。。我认为目的是让这两个变量指向记忆中的同一个对象。也许我已经做了太久了。
- 等等,你确定这是一个深度复制品吗?如果class T没有实现一个复制构造函数,当然不是吗?但也许这只是一个显而易见的事实。
- @好吧,在这种情况下它不会编译。但是示例中的类确实有复制构造函数(它们是由编译器生成的)。
- @阿兰,那就不可能了。内存布局兼容的情况很少(B不向A添加任何数据成员的情况的子集)。
C和vector是完全无关的类型,您必须明确定义这种转换(例如template explicit operator vector () { ... })。
如果这样的转换是一个不常见的任务,这对于类的性质来说是不自然的,那么最好使用范围构造函数(请参见编程人员的答案)。
另外:如果vector是std::vector的话,那么由它衍生出来不是一个好主意。它没有定义为基类,通常您应该更喜欢包含而不是派生(因为它对客户机施加了更宽松的耦合)。
没有办法没有怎么。想象一下,如果您有另一个类,X,派生自BaseA。如果你能得到你的converted对象,你可以在其中插入X的实例,即使原始对象不允许这样做。你会破坏变量的语义。
顺便说一下,你可以在Java中这样做,在那里他们没有真正意义上的泛型,但是在一个强类型的泛型语言中,例如C语言或C++,你将无法做到这一点(C语言中有一个例外,但无论如何你不应该使用它)。
- 在c中使用协方差没有任何错误。
- 当然,在这种情况下是不行的。我会更清楚的。
- 协方差在这里并不重要。转换后的对象是一个副本,保存(可能是切片)原件的副本。将EDOCX1[0]插入其中的效果很好(除了EDOCX1[0]将被切片之外),因为它不会在原始对象中插入任何内容。