以下是我的课程:
ParentClass,ParentObj
DerivedClass(继承自ParentClass),DerivedObj(继承自ParentObj)。
ParentClass有一个受保护的成员:
的std ::矢量< ParentObj *>
DerivedClass仅将DerivedObj *对象分配给此向量。
问题是:
当我使用ParentClass时,我想使用类型为
的迭代器访问其矢量对象的std ::矢量< ParentObj *> :: const_iterator
当我使用DerivedClass时,我想使用类型的迭代器访问其矢量对象:
的std ::矢量< DerivedObj *> :: const_iterator
我怎样才能让它发挥作用?
答案 0 :(得分:4)
您可以在DerivedClass
类中使用虚拟覆盖,返回ParentClass
返回类型的子类型...
struct ParentClass {
virtual ParentObj* get( const size_t index ) {
return m_objects[index];
}
};
struct DerivedClass : public ParentClass {
virtual DerivedObj* get( const size_t index ) {
return dynamic_cast<DerivedObj*>( ParentClass::get(index) );
}
};
两个函数都是相同的'vtable'条目,尽管它们的返回类型不同。
或者,您可以使用相同的技术来创建“继承的”迭代器。
接下来,在DerivedObj*
对象中设置DerivedClass
的向量并不是一个坏主意,只要您保证它们也出现在ParentClass
中。的载体。
答案 1 :(得分:2)
我有一个问题:为什么DerivedClass
继承自ParentClass
?
您是否需要多态行为,或者是否要重用ParentClass
的实现?
继承经常被严重滥用。真。
然后存在容器类的(典型)问题,以及如何公开其元素。不幸的是,迭代器(尽管他们所有的商品)都被语言支持得很差,这与它们应该模仿的指针不同。
因此,提醒:继承是 is-a 关系,对于代码重用,有组合。
在这里,您可以完美地编写一个模板类,它将扮演容器的一部分并提供常用方法。
然后,对于说明问题......你可以编写自己的迭代器,使用正确的基础派生关系,或者你可以选择预先选择多种算法(sort
,foreach
,erase_if
)可以使用用户提供的谓词。
template <class Value>
class Container
{
public:
template <class Pred>
void sort(Pred iPred);
template <class Pred>
Pred foreach(Pred iPred); // maybe a const-version ?
template <class Pred>
size_t erase_if(Pred iPred); // returns the number of erased
private:
std::vector<Value> m_data;
};
然后,上课:
class ParentClass
{
public:
virtual void foo() const;
private:
Container<ParentObj*> m_data;
};
class DerivedClass: public ParentClass
{
public:
virtual void foo() const;
private:
Container<DerivedObj*> m_data;
};
尝试将多态性与代码重用分开,问题应该变得更简单。
答案 2 :(得分:1)
std::vector< ParentObj* >
和std::vector< DerivedObj* >
是两种完全不同的类型,因此您无法隐式地将一种转换为另一种。您可以做的是使用ParentObj*
将每个DerivedObj*
转换为dynamic_cast
。但一般来说,这不是一个好习惯。
答案 3 :(得分:1)
使用基本的C ++继承不能这样做。原因是编译器在DerivedObj
中使用时不知道向量仅包含指向DerivedClass
的指针。关于动态演员的第二次Naveens声明。
您可以使用两个向量std::vector< ParentObj* > mParent
和std::vector< DerivedObj* > mDerived
以及虚拟Add()
函数。基本实现仅添加到mParent
。 Add
中的DerivedClass
功能也会添加到mDerived
。
ParentClass
会有GetParentIterator()
个功能,DerivedClass
会有另一个(附加)功能GetDerivedIterator()
。
答案 4 :(得分:-1)
你的继承设计是错误的。
DerivedClass
不得继承ParentClass
。
ParentClass
有受保护的成员std::vector< ParentObj* >
。
DerivedClass
必须有另一个受保护的成员std::vector< DerivedObj* >
。
您可以创建模板类
template<class T>
struct MyClass {
protected:
std::vector< T* > m_objects;
};
struct ParentClass : MyClass <ParentObj> {};
struct DerivedClass: MyClass <DerivedObj> {};