简体   繁体   English

父对象调用子方法C ++

[英]Parent object call Child method C++

I have somes difficults with inheritance in C++. 我在C ++中继承有些困难。 Suppose I have a class base Parent: 假设我有一个基于班级的父级:

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

}

and 2 classes children Numeric and Symbolic with implement of method Intersection: 并使用方法Intersection的工具为2个子类Numeric和Symbolic子类:

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

}

and a last class ParentVector: 最后一类ParentVector:

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

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

}

I want vector vtParent stock 2 types of object: Numeric or Symbolic. 我想要矢量vtParent库存2种类型的对象:数字或符号。 So I created a vector of Parent objects. 因此,我创建了一个Parent对象的向量。

The problem is: I want get Intersection of 2 vectors ParentVector. 问题是:我想获得2个向量的相交ParentVector。

I can add an object Numeric or Symbolic in vector vtParent but I can not call the method Intersection correspond each type of object. 我可以在向量vtParent中添加对象Numeric或Symbolic,但是我不能调用Intersection对应每种对象类型的方法。 It always call method Intersection of class Parent. 它总是调用类Parent的方法Intersection。

Anyone have some ideas or suggestions ? 有人有什么想法或建议吗? Many thanks. 非常感谢。

//edit : I forgot that the class ParentVector is a child of Parent class, too. // edit:我也忘记了ParentVector类也是Parent类的子级。

// UPDATE: thanks for all your useful helps. //更新:感谢您提供的所有有用帮助。 Now, I want to execute the code below to calculate the Intersection of 2 vectors Parent : 现在,我想执行以下代码来计算2个向量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);
     }
}

I don't write the code of function 'virtual Parent* Parent::Intersection(Parent anotherParent)', so I can not execute the code above. 我没有编写函数'virtual Parent * Parent :: Intersection(Parent anotherParent)'的代码,所以我无法执行上面的代码。 Some one has an idea how to resolve this problem ? 有人知道如何解决这个问题?

// Here, the idea is I want to call function 'Numeric* Intersection(Numeric anotherNumeric)' or 'Symbolic* Intersection(Symbolic anotherSymbolic)' //在这里,想法是我要调用函数'Numeric * Intersection(Numeric anotherNumeric)'或'Symbolic * Intersection(Symbolic anotherSymbolic)'

// FINISH, thanks for all yours suggestion. //完成,谢谢您的所有建议。

Your child classes are changing the return type and parameter type of the Intersection function, which essentially makes it a new function and NOT one that behaves polymorphically. 您的子类正在更改Intersection函数的返回类型和参数类型,这实际上使它成为新函数,而不是表现多态的函数。 The functions must have the same function signature. 这些功能必须具有相同的功能签名。

3 issues in your code: 您的代码中的3个问题:

when store value in STL container, copy constructor will be called, subclass object will be sliced. 当将值存储在STL容器中时,将调用复制构造函数,并将对子类对象进行切片。 so if you want to keep polymorphism of some object, pointer/smart_pointer or reference only can be used. 因此,如果要保留某个对象的多态性,则只能使用指针/ smart_pointer或引用。 in container scenario, pointer/smart_pointer is suitable. 在容器方案中,pointer / smart_pointer是合适的。

std::vector<Parent*> vtParent

parameter type must be identical between base class and derived class. 基类和派生类之间的参数类型必须相同。

issue of return type see 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

}

You are facing object slicing when you push_back an object of Symbolic or Numeric into the vector if you are not using C++11. 您所面临的对象切片,当你push_back ,如果你不使用C ++ 11的符号或数字对象到载体中。 In case of C++11 system will use move symantic to fill the vector if your class definition is adaptable for it, either you should define move constrctor and move assignment operator or depends on default of those functions. 如果您的类定义适用于C ++ 11,则系统将使用移动对称来填充矢量,则应定义移动构造函数和移动赋值运算符,或者取决于这些函数的默认值。

To overcome the object slicing, you can use 要克服对象切片,可以使用

std::vector<Parent*> vtParent;  

in place of use std::vector<Parent> vtParent; 代替使用std::vector<Parent> vtParent;

And virtual functions should keep the same function returns as observed by Ami Tavory and Adam Finley. 虚拟函数应保持与Ami Tavory和Adam Finley观察到的函数返回相同的函数返回。 But in your case you can use as follows since your return types are covariant . 但是在您的情况下,由于返回类型是协变的,因此可以使用以下方法。

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

And please note the virtual destructor is missing from your base class. 并且请注意,您的基类中缺少虚拟析构函数。

Edit: You can simplify your ParentVector::Intersection() as follows. 编辑:您可以简化您的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;
}

Yes this doesnt call delete on things but just to show you the route you need to take 是的,这并不要求删除所有内容,而只是向您显示您需要采取的路线

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM