Amateur
Amateur

Reputation: 160

Parent object call Child method C++

I have somes difficults with inheritance in 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:

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:

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. So I created a vector of Parent objects.

The problem is: I want get Intersection of 2 vectors 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. It always call method Intersection of class Parent.

Anyone have some ideas or suggestions ? Many thanks.

//edit : I forgot that the class ParentVector is a child of Parent class, too.

// UPDATE: thanks for all your useful helps. Now, I want to execute the code below to calculate the Intersection of 2 vectors 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. 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)'

// FINISH, thanks for all yours suggestion.

Upvotes: 0

Views: 1426

Answers (4)

Steephen
Steephen

Reputation: 15824

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. 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.

To overcome the object slicing, you can use

std::vector<Parent*> vtParent;  

in place of use std::vector<Parent> vtParent;

And virtual functions should keep the same function returns as observed by Ami Tavory and 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.

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

Upvotes: 0

john zhao
john zhao

Reputation: 1106

3 issues in your code:

when store value in STL container, copy constructor will be called, subclass object will be sliced. so if you want to keep polymorphism of some object, pointer/smart_pointer or reference only can be used. in container scenario, pointer/smart_pointer is suitable.

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

}

Upvotes: 1

Jason Ball
Jason Ball

Reputation: 153

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

Upvotes: 0

Adam Finley
Adam Finley

Reputation: 1610

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. The functions must have the same function signature.

Upvotes: 4

Related Questions