Parent object call Child method C++ - 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.

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.

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
}

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

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

Related

Is It possible to call methods from a subclass from a base class type?

Hello everyone and thanks for reading,
I'm new to working with classes and I've ran into an issues with making array's of objects,
I have a base class, and an array of the same type, I'd like to know if it's a possibility to
make subclasses of the base class type and put them into an array and call methods that're not
in the base class, sorry if this is a bad question and my apologies if my wording is off,
#include <iostream>
int main()
{
BaseClass* ObjectList[10];
ObjectList[0] = new SubClass;
ObjectList[0]->Load(10);
ObjectList[0]->OtherFunction(); // How Can I Do This?
return 0;
}
class BaseClass
{
public:
virtual void Load(int Num) = 0;
};
class SubClass : public BaseClass
{
void Load(int Num) override
{
std::cout << Num << std::flush;
}
void OtherFunction()
{
// Do Something
}
};
Thanks
Edit -
My intent is to have a simple base class with dozens and dozens of subclasses with different methods, and have an array of the base class,
You can always have more than one pointer (or reference) to the same object.
int main()
{
BaseClass* ObjectList[10];
SubClass TheSubclass;
ObjectList[0] = &TheSubclass;
ObjectList[0]->Load(10); // presumably in a loop
TheSubclass.OtherFunction();
return 0;
}
You will have to downcast your pointer to the real class (or at least a class having the method). You can use either a static_cast if you do not need any control, or a dynamic_cast if you want a run-time validation of the cast:
...
SubClass *psc = dynamic_cast<SubClass *>(ObjectList[0]);
if (psc != nullptr) { // an invalid cast would set it to NULL
psc->OtherFunction();
}
else {
// process the error
}

How to store different objects in an array and get an object of a certain type?

You may have heard of the Entity Component System, where everything is an Entity and each entity has a list of Components which control its functionality.
I am trying to find out how to store different objects (each inherit Component) in an array and be able to get an object out of that array based on their type.
The first solution I can think of would be to have an enum for the types of objects inheriting component:
enum ComponentType : unsigned char // There will never be more than 256 components
{
EXAMPLE_COMPONENT,
ANOTHER_EXAMPLE_COMPONENT,
AND_ANOTHER_EXAMPLE_COMPONENT
};
Then Component base class has a ComponentType type; with a getter, and each child component sets its type e.g:
ExampleComponent::ExampleComponent()
{
type = EXAMPLE_COMPONENT;
}
And then I'd have a GetComponent function:
Component* Entity::GetComponent(ComponentType type)
{
for (unsigned int i = 0; i < m_components.size(); i++)
{
if (m_components.at(i).GetType() == type)
{
return &m_components.at(i);
}
}
return nullptr;
}
// Note: m_components is an std::vector;
And then finally you would call GetComponent e.g:
(ExampleComponent*) component = entity.GetComponent(EXAMPLE_COMPONENT);
The problem with this is that you need an enum for each type of component and you also have to cast the component after using GetComponent to make sure you can access its own member variables.
Does anyone know of a proper way of doing this where there is no need for an enum and there is no need to cast the component? If there is a solution that still requires a type variable to be stored in each component it preferably would be a byte and can't be any bigger than 4 bytes.
Edit: I also don't want to use templates
Thanks in advance!
David
Your approach simulates polymorphism: Having the type as a member and an if statement checking for that type is typically a indication to make use of a class hierarchy. You already stated that you want to use objects derived from the Componenttype, so you should also make proper use of polymorphism.
The second problem in your approach is that you want to filter for a "specific type", which more or less is equivalent to a downcast — i.e. a dynamic_cast<>(): When you pass a certain ComponentType to Entity::GetComponent(), it returns a pointer to Component, but the object behind that pointer is always an object of a specific derived class: In your example you always get an ExampleComponent object, when you pass EXAMPLE_COMPONENT to that function.
The following question arises then naturally: What do you want to do with the object returned by this function? You can only call methods from the Component interface/class, but no method from the derived class! So the downcast hardly makes sense at all (it would, if you would return a pointer to an object of a class derived from Component.
Here is how it looks like using polymorphism and with the downcast in the getComponent() method, returning a pointer to a derived class — note that the method is a template to conveniently implement this for every class derived from Component:
#include <string>
#include <vector>
#include <iostream>
class Component {
public:
virtual std::string getType() = 0;
};
using ComponentContainer = std::vector<Component*>;
class AComponent : public Component { public: virtual std::string getType() { return "A"; }; };
class BComponent : public Component { public: virtual std::string getType() { return "B"; }; };
class CComponent : public Component { public: virtual std::string getType() { return "C"; }; };
class Entity {
public:
template <typename T>
T* getComponent();
void putComponent(Component* c) { m_components.push_back(c); }
private:
ComponentContainer m_components;
};
template<typename T>
T* Entity::getComponent()
{
T* t = nullptr;
for (auto i : m_components) {
if ((t = dynamic_cast<T*>(i)) != nullptr)
break;
}
return t;
}
int main()
{
Entity e;
e.putComponent(new AComponent{});
e.putComponent(new BComponent{});
Component* c;
if ((c = e.getComponent<AComponent>()) != nullptr)
std::cout << c->getType() << std::endl;
// delete all the stuff
return 0;
}
The heavy use of dynamic_cast<>() is problematic both from performance and from design point of view: It should only be used rarely, if ever.
So the design problem may be that everything is stored in a single container? You could instead use several containers, based on "behaviour". As behaviour is implemented in an ECS as a derived class or interface, a getComponent()-similar method of this entity would only return objects of certain (sub-)interfaces. These components would then all implement a given interface method, so the need for down-casting would be eliminated.
For example, given you have "drawable components", this suggests the hierarchy:
// Drawable interface
class DrawableComponent : public Component {
public:
virtual void draw() const = 0;
};
// Drawable objects derive from DrawableComponent
class DComponent : public DrawableComponent {
public:
virtual void draw() const { /* draw the D component */ }
};
Then, an entity could have a container of DrawableComponent objects and you would just iterate over those objects and call draw() on each:
using DrawableContainer = std::vector<DrawableComponent*>;
// m_drawables is a memober of Entity with above type
const DrawableContainer& Entity::getDrawables() { return m_drawables; }
// then just draw those objects
for (auto d : entity.getDrawables())
d->draw(); // no downcast!

Parent class referencing child variable

I have several similar classes inheriting from the same Base-Class/Interface (Base class 1), and they share a couple similar functions, but then also have their own distinct functions. They all also have their own member variables of different classes, and each of those inherits from the same Base-Class/Interface (Base class 2). Is it possible to define a variable in Base class 1, of type Base class 2, then in the actual implementation of classes using Base class 1, have the variable of type Base class 2 be its proper type. Kinda hard to explain, so simplified example below.
//Base-Class 1
class Shape
{
public Shape() {}
ShapeExtra m_var;
//The common functions
public GetVar(){ return m_var; }
}
class Circle : Shape
{
public Circle() { m_var = new CircleExtra(); }
public void CircleFunc()
{
m_var.CircleExtraFunc();
}
}
class Triangle : Shape
{
public Triangle() { m_var = new TriangleExtra(); }
public void TriangleFunc()
{
m_var.TriangleExtraFunc();
}
}
.
.
.
//Base_Class 2
class ShapeExtra
{
public ShapeExtra() {}
}
class CircleExtra : ExtraClass
{
public CircleExtra() {}
void CircleExtraFunc() {//Do stuff}
}
class TriangleExtra : ExtraClass
{
public TriangleExtra() {}
void TriangleExtra() {//Do stuff}
}
.
.
.
So, I need the m_var in the child classes to be kept it as its own unique version. Because right now (w/o the extra CircleExtra m_var;), the GetVar() works, but in CircleFunc, m_var is still type of ShapeExtra, and thus doesn't know that CircleExtraFunc exists. I could cast m_var each time I wanted to do that, but that is repetitive and not worth it in my real-world case. Is there a way to utilize the functions in unique classes based off of ShapeExtra, while keeping the GetVar() function in Shape?
Please ask questions if there is anything I left out.
Simply with inheritance and without using pointers it is not possible, as C++ is a statically-and-strictly-typed language.
You can inherit both the variable and the function, but you'll need to cast function return value.
You can also override the function to make it return the concrete type, but then you have to cast the variable inside the function.
You can also declare the same var with the concrete class in subclasses, but then you just hide the variable in the superclass and inherit nothing.
I'd rather go for a solution using templates. Make the type of the variable a template type and extend the template using a concrete type in subclasses. It'll work perfectly.
It's been a long time since I last programmed in C++ and I beg your pardon if there are errors in the following example. I'm sure you can easily make it work.
template <class S>
class Shape {
S m_var;
//......
public:
S var () {
return m_var;
}
//.......
}
class Circle: Shape <CircleExtra> {
// var method returns CircleExtra
//......
}
Edit:
Regarding some comment, to allow virtual invocation of the method, it is possible to use correlated return types. Something like the following example.
class Shape {
public:
virtual ShapeExtra *var () = 0;
}
template <typename SE>
class ConcreteShape: Shape {
public:
virtual SE *var() {
return &m_var;
}
// Constructor, etc.
private:
SE m_var;
}
Or some variation. Now concrete shapes can benefit from extending the template, as long as SE * is correlated with ShapeExtra * (the type parameter extends ShapeExtra). And you can vall the method transparently through Shape interface.
Using pointers, this is totally possible.
Using your example, you could do something like this:
#include <iostream>
#include <memory>
using namespace std;
//Extras
class ShapeExtra
{
public:
ShapeExtra() {}
void ShapeFunc() { std::cout << "Shape"; }
virtual ~ShapeExtra() = default; //Important!
};
class Shape
{
public:
std::unique_ptr<ShapeExtra> m_var;
//require a pointer on construction
//make sure to document, that Shape class takes ownership and handles deletion
Shape(ShapeExtra* p):m_var(p){}
//The common functions
ShapeExtra& GetVar(){ return *m_var; }
void ShapeFunc() {m_var->ShapeFunc();}
};
class CircleExtra : public ShapeExtra
{
public:
void CircleExtraFunc() {std::cout << "Circle";}
};
class Circle : public Shape
{
CircleExtra* m_var;
public:
Circle() : Shape(new CircleExtra()) {
m_var = static_cast<CircleExtra*>(Shape::m_var.get());
}
void CircleFunc()
{
m_var->CircleExtraFunc();
}
};
int main() {
Circle c;
//use the ShapeExtra Object
c.GetVar().ShapeFunc();
//call via forwarded function
c.ShapeFunc();
//call the circleExtra Function
c.CircleFunc();
return 0;
}
Test it on ideone
Note the use of pointers and a virtual destructor:
By using a virtual destructor in the ShapeExtra base class, you make it possible to destruct an object of any derived class, using a ShapeExtra*. This is important, because
by using a std::unique_ptr<ShapeExtra> instead of a plain C-pointer, we make sure that the object is properly deleted on destruction of Shape.
It is probably a good idea to document this behaviour, i.e. that Shape takes the ownership of the ShapeExtra*. Which especially means, that we do not delete CirleExtra* in the Circle destructor
I decided here to require the ShapeExtra* on construction, but its also possible to just use std::unique_ptr::reset() later and check for nullptr on dereferencing Shape::m_var
Construction order is this: On calling the constructor of Circle, we first create a new CircleExtra which we pass to Shape before finally the constructor of Circle is executed.
Destruction order is Circle first (was created last), then Shape which also destructs the ShapeExtra for us, including (via virtual function) the CircleExtra
I would recommend the following approach:
class ShapeExtra
{
public:
virtual ~ShapeExtra() { }
virtual void SomeCommonShapeFunc() { std::cout << "Shape"; }
};
class Shape
{
public:
virtual ShapeExtra &GetVar() = 0; // Accessor function.
};
Note that the class Shape does not have any data members at all. After that for each derived class you need:
class CircleExtra : public ShapeExtra
{
public:
void SomeCommonShapeFunc() { std::cout << "Circle"; }
};
class Circle : public Shape
{
CircleExtra m_var; // Data member with circle specific class.
public:
virtual ShapeExtra &GetVar() { return m_var; }
};
Implementation of virtual method in Circle will return reference to the base class ShapeExtra. This will allow using this extra in the base class.
Note that pointers and templates are not used at all. This simplifies the overall design.

Boost ptr_list accessing subclass methods

To start out, I am just returning to c++ from a 20 or so year absence. I am just working to figure out some stuff. I want to create a class hierarchy and instantiate subclasses of a base class into a list and iterate on the list and get the subclass back in the iterator or find a way to accomplish this.
namespace FooBar {
class ace {
public: ace::ace(){};
public: virtual int ace::getValue(){ return 1; };
};
class base : public ace {
public: base::base(){};
**// Added method for casting
public: base::base(ace){};**
public: int base::getValue(){ return 2; };
};
class face : public ace {
public: face::face(){};
**// Added method for casting
public: face::face(ace){};**
public: int face::getValue(){ return 3; };
};
}
I create instances of the appropriate sub class to insert on the list. I can't sort out how to get the sub class back from the iterator. I've tried adding an identifier so I would know which class it was, but I can't work out how to cast the iterator.
int main() {
using namespace FooBar;
boost::ptr_list<ace> theList;
for (int i = 0; i < 10; i++){
ace* foo;
if (i % 2 == 0)
foo = new base();
else
foo = new face();
theList.push_back(foo);
}
for (boost::ptr_list<ace>::iterator iter = theList.begin(); iter != theList.end(); iter++){
std::cout << (*iter).getValue() << ", ";
// cast to sub class; Is it of type base
if (typeid(base) == typeid(*iter)){
base bar = static_cast<base>(*iter);
}
else {typeid(face) == typeid(*iter)){
face bar = static_cast<face>(*iter);
}
}
}
the output is 1, 1, ...
Both casts above fail with no suitable user-defined conversion from ace to base/face exists;
So, I created a constructor for both base and face as shown in added comment;
and the error I now get is
ace::ace(const ace &) cannot be references it is a deleted function.
Any guidance would be appreciated.
I can't sort out how to get the sub class back from the iterator
You can't, the way you currently have it set up. C++ has no run time type information (rtti) except for classes which are polymorphic (classes which have at least one virtual function).
You can make getValue virtual (just write virtual before it), and not need to get a pointer to the derived class from a pointer to the base class. That would be the idiomatic solution here.
If you actually had a case you needed to get a derived type from a base type pointer (and the class had a virtual function) you can either use dynamic_cast or a combination of typeid and static_cast to figure out what the derived type is.

Passing object into array that are of the same parent class

As I am still somewhat new to programming in C++ I was just curious if it were possible to pass objects pointers to an array in order for code consolidation.
Header file like such;
class.h
class parent
{
some information.....
};
class child1 : public parent
{
some information.....
};
class child2 : public parent
{
some information.....
};
Main file like such;
main.cpp
#include "class.h"
int main()
{
child1 instanceChild1;
child2 instanceChild2;
child1* pointer1 = &instanceChild1;
child2* pointer2 = &instanceChild2;
parent array[2] = {pointer1 , pointer2};
}
I am trying to achieve such so that I may create a function that uses a dynamic array in order to hold object pointers so that I may dereference them in the function and manipulate them accordingly. Though I am having issues getting the different pointers to work together when going into an array. I need such functionality since there will be many different objects(all under the same parent) going in and out of this function.
Yes it is possible.
But you need to declare the array like this
parent * arr[] = { ... }
or it would be better if you use a vector
vector<parent *> arr;
arr.push_back(childPointer);//For inserting elements
as #pstrjds and #basile has written
and if you want to use child specific member functions, you can use dynamic cast
ChildType1* ptr = dynamic_cast<ChildType1*>(arr.pop());
if(ptr != 0) {
// Casting was succesfull !!! now you can use child specific methods
ptr->doSomething();
}
else //try casting to another child class
** your compiler should support RTTI in order for this to work correctly
you can see this answer for details
I prefer to use pure Virtual functions like this
class A {
public :
enum TYPES{ one , two ,three };
virtual int getType() = 0;
};
class B : public A{
public:
int getType()
{
return two;
}
};
class C : public A
{
public:
int getType()
{
return three;
}
};