父对象调用子方法C ++

时间:2015-06-18 13:43:36

标签: c++ inheritance

我在C ++中有一些继承困难。假设我有一个基类Parent:

class Parent{
public:
      ...
      virtual Parent Intersection(Parent anotherParent);

}

和2个类子数字和符号用方法交叉实现:

class Numeric : public Parent{
public:
      ...
      Numeric Intersection(Numeric anotherNumeric)
      {
       ...
      }; // do intersection with another object numeric

}

// class Symbolic
class Symbolic : public Parent{
public:
      ...
      symbolic Intersection(Symbolic anotherSymbolic)
      {
       ...
      }; // do intersection with another object symbolic

}

和最后一个班级的ParentVector:

class ParentVector : public Parent{
public:
      ...
      ParentVector Intersection(ParentVector anotherParentVector);

private:
      std::vector<Parent> vtParent; // vector stock object Parent (Numeric or Symbolic)

}

我想要矢量vtParent库存2种类型的对象:数字或符号。所以我创建了一个父对象的向量。

问题是:我想得到两个向量的交叉点ParentVector。

我可以在向量vtParent中添加一个对象Numeric或Symbolic但是我不能调用方法Intersection对应每种类型的对象。它总是调用类Parent的方法交集。

任何人都有一些想法或建议?非常感谢。

//编辑:我忘记了ParentVector类也是Parent类的子类。

//更新:感谢您提供的所有有用帮助。现在,我想执行下面的代码来计算两个向量的交集:Parent:

ParentVector* Intersection(ParentVector anotherParentVector){
     ParentVector* result;
     Parent* tmp;

     for( int i = 0; i < this->vtParent.size(i); i++ ){
           // PROBLEM with this line because I don't write the code of 
           // function 'virtual Parent* Parent::Intersection(Parent anotherParent)'

          *tmp = this->vtParent.at(i)->Intersection(anotherParentVector.getParentVector().at(i));
          result->getParentVector.push_back(tmp);
     }
}

我没有编写函数代码&#39;虚拟Parent * Parent :: Intersection(Parent anotherParent)&#39;,所以我无法执行上面的代码。有人知道如何解决这个问题吗?

//这里的想法是我想调用函数&#39; Numeric * Intersection(Numeric anotherNumeric)&#39;或者&#39; Symbolic * Intersection(Symbolic anotherSymbolic)&#39;

//完成,感谢你的所有建议。

4 个答案:

答案 0 :(得分:4)

您的子类正在更改Intersection函数的返回类型和参数类型,这实际上使它成为一个新函数而不是多态行为。这些函数必须具有相同的函数签名。

答案 1 :(得分:1)

代码中有3个问题:

当STL容器中存储值时,将调用复制构造函数,子类对象将被切片。所以如果你想保持某些对象的多态性,可以使用指针/ smart_pointer或reference。在容器场景中,指针/ smart_pointer是合适的。

std::vector<Parent*> vtParent

参数类型在基类和派生类之间必须相同。

返回类型问题请参阅enter link description here

class Parent{

public:

  ...
  virtual Parent& Intersection(Parent anotherParent);

}


class Symbolic : public Parent{
public:
      ...
      symbolic& Intersection(Symbolic anotherSymbolic)
      {
       ...
      }; // do intersection with another object symbolic

}

答案 2 :(得分:0)

如果您不使用C ++ 11,则当您将push_back符号或数字对象放入向量时,您将面临对象切片。在C ++ 11的情况下,如果您的类定义适合它,系统将使用移动语义来填充向量,您应该定义移动构造函数和移动赋值运算符,或者取决于这些函数的默认值。

要克服对象切片,可以使用

std::vector<Parent*> vtParent;  

代替使用std::vector<Parent> vtParent;

虚拟函数应保持与Ami Tavory和Adam Finley所观察到的相同的函数返回。但在你的情况下,你可以使用如下,因为你的返回类型是协变的。

virtual Parent* Intersection(Parent anotherParent);
symbolic* Intersection(Symbolic anotherSymbolic);
Numeric* Intersection(Numeric anotherNumeric);

请注意您的基类中缺少虚拟析构函数。

编辑: 您可以按照以下方式简化ParentVector::Intersection()

std::vector<Parent*> Intersection(ParentVector anotherParentVector){
     std::vector<Parent*> result;
     Parent * tmp;
     std::vector<Parent*>::iterator it= vtParent.begin();
     for( ; it != vtParent.end(); ++it){
           tmp=    it->Intersection(anotherParentVector.getParentVector().at(i));
          result->getParentVector.push_back(tmp);
     }
     return result;
}

答案 3 :(得分:0)

是的,这并不会调用删除内容,只是为了向您显示需要采取的路线

#include <iostream>
#include <vector>
#include <memory>
class Parent{
public:
    virtual Parent* Intersection() = 0;
};

class Numeric : public Parent{
public:
    Parent* Intersection()
    {
        std::cout << "\nNumeric!";
        return new Numeric;
    } // do intersection with another object numeric

};

// class Symbolic
class Symbolic : public Parent{
public:
    Parent* Intersection()
    {
        std::cout << "\nSymbolic!";
        return new Symbolic;
    } // do intersection with another object symbolic

};

class ParentVector{
public:
    ParentVector()
    {
        vtParent.push_back(std::make_unique<Symbolic>());
        vtParent.push_back(std::make_unique<Numeric>());
    }
    void print()
    {
        for (const auto& e : vtParent) {
            e->Intersection();
        }
    }
    ParentVector Intersection(ParentVector anotherParentVector);

private:
    std::vector<std::unique_ptr<Parent>> vtParent; // vector stock object Parent (Numeric or Symbolic)

};


int main()
{
    ParentVector pvec;
    pvec.print();

    std::cout << '\n';
    system("PAUSE");
    return 0;
}