Base and child class function inheritance confusion (C++) - c++

I am very confused about base and child class function inheritance.
I have those classes:
#include <point.h>
class Polygon{
public:
Polygon();
virtual ~Polygon();
void addPoint(Point *p);
std::string getType();
Point* getPoint(int index);
int getNumOfPoints();
int getColor();
virtual int area()=0;
private:
std::vector<Point*> _points;
int color;
std::string type = "Polygon";
};
class Rectangle : public Polygon{
public:
Rectangle();
virtual ~Rectangle();
virtual int area();
private:
std::vector<Point*> _points;
int color;
std::string type = "Rectangle";
};
Now, in the main I do this:
Rectangle rect();
rect.getType();
this gives me "Polygon" while I want "Rectangle"
I am quite sure I am confused with inheritance. So, according to how I understand, the base class functions get inherited, but why is it when I run the function it relates to the members of the object base class but not the actual object (Rectangle)?
Will be happy if someone would help!
Much appreciated

What happens is that Rectangle::type is completely unrelated to Polygon::type. It's a separate data member that just happens to have the same name.
One way to achieve the desired effect is by making getType() virtual and overriding it in every derived class:
class Polygon {
public:
virtual std::string getType() = 0;
...
}
class Rectangle: public Polygon {
public:
virtual std::string getType();
...
}
std::string Rectangle::getType() {
return "Rectangle";
}

You have two members named type in an instance of Rectangle. Since private members of Polygon are only accessible to the member functions of that class, it's as if they didn't exist when it comes to declaring members by the same name in Rectangle. It's not even shadowing proper, because in Rectangle, the type member of Polygon would not be accessible. So Polygon::getType returns the type defined in Polygon and not the unrelated one defined in Rectangle.
You have several ways to solve your issue:
Define type as a protected member in Polygon and assign to it in every constructor.
Drop type; declare getType as virtual and override it in every class, returning a constant string.
Use RTTI for what it's good for: finding out the actual class of an object.
Design your program so that you don't need to tell the exact type of an object. This is usually best. Every time you need different behavior for different subclasses of Polygon, write a virtual member function that implements the specific behavior.

You only need the type string in one place - your base class. Because you want it to be accessible in your derived classes but not to your user, make it protected. In each constructor, set it to the appropriate value:
Polygon::Polygon():
type("polygon")
{}
Rectangle::Rectangle()
Polygon()
{
type = "rectangle";
}

Related

How do I access member functions of concrete class when I'm using Polymorphism and inheritance to declare it as a pointer to the concrete class

Say I have an abstract class.
class shape{
public:
shape();
double getWidth();
private:
float m_center;
};
and I have a class that inherits from shape.
class triangle : public shape{
public:
triangle(vector<double> a, vector<double> b, vector<double> c);
vector<double> getPoints();
void setPoints();
private:
double pointA, pointB, pointC;
};
Then say my code is formatted so that when I dealing with shapes I get the shape data in the form of shape pointers. However there are times when I need to access the member functions of the Triangle class, but I only have the shape*
int main(){
shape* generalShape = new triangle()
std::cout << generalShape -> getWidth() << std::endl;
std::vector<double> tempVector = generalShape -> getPoints(); //<- can't do this part.
So I can't call member functions from the shape* object so I was just wondering if there is a way to do this or if I have my code structured completely wrong.
Assuming it doesn't make sense to use a virtual function in the base class, you can achieve this doing a dynamic_cast. There does need to be at least one virtual function in base class.
triangle* newPtr = dynamic_cast<triangle*>(generalShape);
One should understand the costs and advantages of this approach (run-time polymorphism); and consider whether it is more efficient to redesign the class.

If base class pointer cannot access derived class member function, then what is so convenient about polymorphism?

To realize Polymorphism, we need to use a base class pointer to a derived class instance. Everything about polymorphism is good except, what if every derived class has one or several its own member function? If the base class pointer cannot access these derived class member function, then what is so convenient about polymorphism?
Below is an example. "shape" is a base class. "square" and "circle" are two derived classes.
class shape {
public:
virtual void getArea()=0;
};
class square: public shape {
private:
int edge;
public:
square(){edge = 1;}
virtual void getArea(){ //polymorphism
cout << edge*edge << "\n";
}
void getNumberOfEdge(){ //a new member function
cout << "4\n";
}
};
class circle: public shape {
private:
int radius;
public:
circle(){radius = 1;}
virtual void getArea(){ //polymorphism
cout << 3*radius*radius << "\n";
}
void getCurvature(){ //a new member function
cout << 1/radius << "\n";
}
};
int main(){
shape* arr[2] = {
new square(),
new circle()
};
arr[0]->getArea();
arr[1]->getArea();
arr[0]->getNumberOfEdge(); //compiler error
}
getArea() is a good example of realizing polymorphism. However accessing derived class member function gives me compiler error, which I understand why perfectly. But from a designing point of view, we do not want to add a bunch of virtual functions to the base class just for the sake of each derived class, right?
Functionality in the base class should be in the base class. Functionality that's specific to specific derived classes should be in those derived classes. The virtual functions let code manipulate shapes and perform operations that are valid for any shape without having to understand how to perform those functions on every possible type of shape that may exist now and in the future.
But from a designing point of view, we do not want to add a bunch of virtual functions to the base class just for the sake of each derived class, right?
If those operations make sense on the base class, then they should probably go there. If they are shape-specific, then they belong in the specific classes for which that functionality makes sense.
Say you have a system that uses shapes but has no derived class for octagon. The point of polymorphism is that code can be written today that will work perfectly on octagons later should someone add them.
With the proper types you can work the number of edge problems quite well, taking polymorphism to the edge!
Let's add a class:
// a base interface for all Edged shapes
struct HasEdges {
virtual void getNumberOfEdges() const = 0;
// side note: I'd prefer this getter to return an int
// but keeping it as in the example
};
Now for Square (but not for Circle!) we can do:
class Square: public Shape, public HasEdges {
// ...
public:
void getNumberOfEdges() const override { /* implement */ }
// ...
};
And the main would go like this:
int main(){
shape* arr[2] = {
new square(),
new circle()
};
arr[0]->getArea();
arr[1]->getArea();
// some edgy thing below
HasEdges* hasEdges = dynamic_cast<HasEdges*>(arr[0]);
// above returns null on failure
if(hasEdges) hasEdges->getNumberOfEdges();
// releasing memory...
}
Run-time Polymorphism means polymorphic behavior at run time.
The behavior defined by getArea() is changed at run time based on the instance it points to.
So, you are mixing with polymorphism with static compiling problem. Base class does not have a member function name getNumberOfEdge() and you get compiler error.
If you want to have specific implementation called, why not make compiler see it and cast it?
public:
virtual void getArea()=0;
template<typename T>
const T * get() {
return dynamic_cast<T *>(this);
}
};
Now you can cast it to whatever derived type:
auto square_instance = arr[0]->get<square>();
if (square_instance) {
square_instance->getNumberOfEdge();
}
A different approach to run time polymorphism is suggested by Sean Parent. I liked it and trying this approach more often now.

c++ Pure virtual functions dependent on derived classes

I am working on a bounding box/collision detection system and I am using different types of bounding volumes, id like all the bounding volumes to derive the same base class and then using pure virtual functions forcing all derived classes to implement basic functions like
isCollidingWith(BoudingBox)
But here is what giving me trouble: I wan't them to implement a function for every BoudingVolume type. So if I have a bounding box and a bounding sphere, both the sphere class and the box class should implement
isCollidingWith(BoundingBox)
isCollidingWith(BoundingSphere)
If i then create a new BoundingVolume like BoundingCylinder (by deriving from the base class), i want the compiler to throw an error until BoundingBox and BoundingSphere has implemented the isCollidingWith function for the new Cylinder type (and ofc until the Cylinder has implemented the isCollidingWith for the Box, Sphere and the Cylinder.
Im not sure on how to go about implementing this, but I thought about using CRTPs.
Is this even possible?
When you make pure virtual function in base class, then it is compulsory for derived class for its implementation, if derived class doesn't implement it then compiler will give you an error. so you don't have to take care whether the pure virtual functions are implemented or not.
It is possible to concoct such a thing with CRTP
class BoundingBox;
class BoundingSphere;
class Shape
{
public:
virtual bool isIntersecting(const BoundingBox&) const = 0;
virtual bool isIntersecting(const BoundingSphere&) const = 0;
};
class BoundingVolumeBase
{
public:
virtual bool checkIntersection(const Shape&) const = 0;
virtual ~BoundingVolumeBase();
};
template<class Derived>
class BoundingVolume : public BoundingVolumeBase
{
bool checkIntersection(const Shape& shape) const override
{
return shape.isIntersecting (static_cast<const Derived&>(*this));
}
};
class BoundingBox : public BoundingVolume<BoundingBox> {
// ...
};
class BoundingSphere : public BoundingVolume<BoundingSphere> {
// ...
};
Now if we invent a new kind of BoundingVolume, it will not compile until a new function is added to Shape.
class BoundingCylinder : public BoundingVolume<BoundingCylinder> {
// ...
};
BoundingCylinder bc; // <-- this will not compile
It is not necessary to do it this way. Any method that uses virtual functions as the sole kind of type-based dispatch will work (you will likely end up with something roughly equivalent to the above anyway). If you depend on typeid or on a custom type identifier, you may encounter problems though.
The downside of this method is mutual dependence of class Shape and all concrete kinds of BoundingVolume.

How do I access abstract private data from derived class without friend or 'getter' functions in C++?

So, I am caught up in a dilemma right now. How am I suppose to access a pure abstract base class private member variable from a derived class?
I have heard from a friend that it is possible to access it through the base constructor, but he didn't explain. How is it possible?
There are some inherited classes from base class. Is there any way to gain access to the private variables ?
class Base_button
{
private:
bool is_vis;
Rect rButton;
public:
// Constructors
Base_button();
Base_button( const Point &corner, double height, double width );
// Destructor
virtual ~ Base_button();
// Accessors
virtual void draw() const = 0;
bool clicked( const Point &click ) const;
bool is_visible() const;
// Mutators
virtual void show();
virtual void hide();
void move( const Point &loc );
};
class Button : public Base_button
{
private:
Message mButton;
public:
// Constructors
Button();
Button( const Point &corner, const string &label );
// Acessors
virtual void draw() const;
// Mutators
virtual void show();
virtual void hide();
};
I want to be able access Rect and bool in the base class from the subclass
It is not possible. Private members are only accessible in the class in which they are defined (plus its friends), by design.
Every class is solely responsible for its private member variables. If a subclass needs to access those, they either have to be declared protected or, preferably, accessed indirectly through some public or protected methods provided by the base class.
Most of the times, if you really think you must have access to the base class' privates, this indicates bad design of either the base class or your subclass!
UPDATE
Thanks for the code! Why do you want to access rRect and is_vis? I guess you can access the latter through Base_button::is_visible() and Base_button::show(), Base_button::hide().
If all you want to do is pass the geometry information from your subclass constructor to the base class, you could indeed call the base constructor:
Button::Button(const Point &corner, const string &label)
: Base_button(corner, 100, 100) // Presumably, this initializes rRect
{
// ...
}
Is it possible to change the base class member to protected? That is the direct way of making it accessible to subclasses. I don't know what your friend was referring to, other than that the constructor of your derived class calls the constructor of the base class, and the base class's constructor can see the base class's private members.

can a class have virtual data members?

class Base{
public:
void counter();
....
}
class Dervied: public Base{
public:
....
}
void main()
{
Base *ptr=new Derived;
ptr->counter();
}
To identify that the base class pointer is pointing to derived class and using a derived member function, we make use of "virtual".
Similarly, can we make derived data members "virtual"? (the data member is public)
virtual is a Function specifier...
From standard docs,
7.1.2 Function specifiers
Function-specifiers can be used only in function declarations.
function-specifier:
inline
virtual
explicit
So there is nothing called Virtual data member.
Hope it helps...
No, but you can create a virtual function to return a pointer to what you call virtual data member
No, in C++ there are no virtual data members.
I think not, but you might simulate it using virtual getters and setter perhaps?
To identify that the base class pointer is pointing to derived class and using a derived member function, we make use of "virtual".
That is not correct. We make virtual functions to allow derived classes to provide different implementation from what the base provides. It is not used to identify that the base class pointer is pointing to derived class.
Similarly, can we make derived data members "virtual"? (the data member is public)
Only non static member functions can be virtual. Data members can not be.
Here's a link with some more info on that
No, because that would break encapsulation in a myriad of unexpected ways. Whatever you want to achieve can be done with protected attributes and/or virtual functions.
Besides, virtual functions are a method of dispatch (i.e. selecting which function is going to be called), rather than selecting a memory location corresponding to the member attribute.
A class cannot have a virtual member, see for instance this answer.
However, you can have something similar using pointers, inheritance
and runtime polymorphism.
In the following snippet I define the prototype for a geometrical shape,
that has an area method. The picture class has a member shape* s;
and the methods of that shape pointed by s are used by picture::show().
In this setup it is undesirable to have an instance of picture before
an actual implementation of a shape has been given, hence we force picture to be
abstract by adding a dummy virtual function picture::make_real().
// prototypes
class shape
{
public:
virtual double area() = 0; // to be defined later
};
class picture
{
protected:
shape* s;
virtual void make_real() = 0; // force picture to be abstract
public:
picture(shape* ptr):
s{ptr}
{}
void show()
{
std::cout << s->area() << '\n';
}
};
Next, we actually implement a shape called square and a picture type
square_picture that (literally) has a square shape.
// actual implementation
class square : public shape
{
double len;
public:
square(double l):
len{l}
{}
double area() override
{
return len*len;
}
};
class square_picture : public picture
{
void make_real() override {} // square_picture is not abstract
public:
square_picture(double l):
picture{new square{l}}
{}
~square_picture()
{
delete s;
}
};
The class square_picture can be tested with the following snippet
int main()
{
square_picture A{2.0};
A.show();
//picture B{nullptr}; // error: picture is abstract
return 0;
}
which outputs:
4
I have a base class which uses an array of objects. From that class I derived a new class that uses an array of a different type of object. Both variables have exactly the same name. Virtual member functions were added to both classes to process the arrays. These member functions have no trouble finding the correct variable. The member functions and the variables they use are in a common scope.
The virtual member functions are nearly identical in both classes. Only the type of array changed.
C++ templates could have accomplished the same result.
Maybe you can see the problem in a equivalent way:
class VirtualDataMember{
public:
...
}
class DerviedDataMember: public VirtualDataMember{
public:
...
}
class Base{
public:
VirtualDataMember* dataMember;
void counter();
...
}