C ++继承问题

时间:2009-11-24 11:20:21

标签: c++ class inheritance

以下是我的课程:

  

ParentClass,ParentObj

     

DerivedClass(继承自ParentClass),DerivedObj(继承自ParentObj)。

ParentClass有一个受保护的成员:

  

的std ::矢量< ParentObj *>

DerivedClass仅将DerivedObj *对象分配给此向量。

问题是:

当我使用ParentClass时,我想使用类型为

的迭代器访问其矢量对象
  

的std ::矢量< ParentObj *> :: const_iterator

当我使用DerivedClass时,我想使用类型的迭代器访问其矢量对象:

  

的std ::矢量< DerivedObj *> :: const_iterator

我怎样才能让它发挥作用?

5 个答案:

答案 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 关系,对于代码重用,有组合

在这里,您可以完美地编写一个模板类,它将扮演容器的一部分并提供常用方法。

然后,对于说明问题......你可以编写自己的迭代器,使用正确的基础派生关系,或者你可以选择预先选择多种算法(sortforeacherase_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* > mParentstd::vector< DerivedObj* > mDerived以及虚拟Add()函数。基本实现仅添加到mParentAdd中的DerivedClass功能也会添加到mDerived

ParentClass会有GetParentIterator()个功能,DerivedClass会有另一个(附加)功能GetDerivedIterator()

答案 4 :(得分:-1)

你的继承设计是错误的。

DerivedClass不得继承ParentClassParentClass有受保护的成员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> {};