c++ - inheritance- the same method name in two different classes - c++

I'm new in C++ and I have maybe easy for you question.
class circle {
protected:
int r;
public:
circle(int re) { r=re; }
double surface() {
return 3.14*r*r;
}
};
class sphere : public circle {
public:
sphere(int r) : circle(r) {}
double surface(){
return 4*3.14*r*r;
}
};
And now, my problem is how I can do something like that: create a sphere object and using it to get surface not of a sphere but of a circle. Can I use somehow the same methods names in two classes, when one is inherited by the second one?

You can have access to the base class' surface method by appending circle:: before its name :
sphere sph(1);
double s = sph.circle::surface();

Your design is initially wrong. Public inheritance in C++ means that the child is-a specific kind of the parent. A sphere is not a circle!
Besides, if you do want to get the surface area of the sphere, you should make your surface function virtual:
class Circle {
public:
virtual double surface();
};
That way, when you override it in Sphere, the Sphere version will be called.

Related

Inheritance depth, Single responsability or DRY

Let's say I want to implement three different classes: Square, ColoredSquare, TexturedSquare.
Since ColoredSquare is a Square with a color and TexturedSquare is a ColoredSquare with a texture, my first thought was to have them all deriving from each other:
class Square {
Square::Square(position)
: position_(position)
{
}
}
class ColoredSquare : public Square {
ColoredSquare::ColoredSquare(position, color)
: Square(position), color_(color)
{
}
}
class TexturedSquare: public ColoredSquare {
TexturedSquare::TexturedSquare(position, color, texture)
: ColoredSquare(position, color), texture_(texture)
{
}
};
However, I remembered reading that having too much inheritance depth was bad practice (and that generally, classes should only be deriving from abstract classes).
So I thought about switching to a single class:
class Square {
Square::Square(glm::vec3 position)
: position_(position), type_(SquareType::Basic)
{
}
Square::Square(glm::vec3 position, glm::vec4 color)
: position_(position), color_(color), type_(SquareType::Colored)
{
}
Square::Square(glm::vec3 position, glm::vec4 color, glm::vec2 texture)
: position_(position), color_(color), texture_(texture), type_(SquareType::Textured)
{
}
};
Now, while I find it acceptable for now, I'm thinking it might be unpractical in the future (I won't be able to use polymorphism) and I'm also wondering if this is in breach of the Single Responsability Principle.
What would be the best way to implement this hierarchy structure in a clean, extensive way?
I don't think there's one correct answer to this question, but there are other approaches available.
One could be to multiply inherit from pure virtual classes and implement them in the derived class:
class Texture {};
class Color {};
class Square {};
class ITextured { public: virtual void setTexture(Texture) = 0; };
class IColored { public: virtual void setColor(Color) = 0; };
class ColoredSquare : public IColored, public ITextured, public Square {
Texture tex;
Color col;
public:
virtual void setTexture(Texture t) { tex = t; }
virtual void setColor(Color c) { col = c; }
};
This avoids having issues like Square inherit from Rectangle although a Rectangle method might alter only height, leaving the derived square class in violation of square-ness.
Composition is another approach, and there are many ways to implement similar ideas.

typecasting and check is an instance exists in a vector

I have a virtual class Shape. class Rectangle, Triangle, Circle inherit from Shape and have different characteristics (size, number of side...).
I want to store different shape in a structure (let's say a vector).
so my vector would be: vector<Shape*> myvec;
I would like to know how it is possible to know if a given instance of a shape is present in the vector (ex: new Circle(diameter 10);).
I have heard about dynamic cast but I don't understand at all how to use it?
class Shape
{
public:
Shape(){}
virtual int Size()=0;
virtual int Sides()=0;
virtual bool isequal(const Shape & rhs)=0;
int size,sides;
};
class Circle : public Shape
{
public:
Circle(int diameter):size(diameter)
{
sides=0;
}
bool isequal(const Circle &rhs)
{
return size==rhs.size;
}
int size,sides;
};
class Rectangle: public Shape
{
Rectangle(int nbsides,int size1,int size2 ): sides(nbsides),size1(size1),size2(size2){}
bool isequal(const Rectangle &rhs)
{
return (size1==rhs.size1 && rhs.size2==size2);
}
int sides,size1,size2;
};
dynamic_cast is right:
Shape* shape = myvec[0];
Circle* circle = dynamic_cast<Circle*>(shape);
if(circle != nullptr)
; // it's a Circle! Do something circly.
else
; // it's not a Circle. Do something else.
But a better answer to the question is that, in a perfect world, you should use polymorphism such that it is rarely if ever necessary to do this.
Based on the additional comments below, I think you might want to use a pure virtual isequal() in Shape, with dynamic_casts inside the various implementations (the inside of a polymorphic comparison function is one of the few places I can use dynamic_cast without feeling the need to wash my hands afterwards :) ).
// edited out code that isn't directly relevant
class Shape
{
public:
virtual bool isequal(const Shape& rhs)=0;
};
class Circle : public Shape
{
public:
// snip
virtual bool isequal(const Shape &rhs) override
{
Circle* rhsAsCircle = dynamic_cast<Circle*>(&rhs);
if(rhsAsCircle == nullptr)
return false; // not a Circle; can't be equal
return size==rhsAsCircle->size;
}
};
Then elsewhere:
Circle searchCircle(10);
for(Shape* shape : myvec)
if(shape->isequal(searchCircle))
; // we have a match!

How to reference a variable without knowing the specific type?

I'm fairly new to C++, and still trying to get my head around some of the finer points of intermediate-level concepts such as templates/writing generic code. I'm writing an application using OpenSceneGraph (OSG), and basically this is what I'm trying to do:
I want to have a general element class that can handle any number of different element 'types'
Each instance of the general element class should contain a different shape (depending on the type)
The different element types (and the shapes they're mapped to) will only be discovered at run-time, because they're going to depend on source data - e.g. there could be 6 different element types that are all represented by boxes of different sizes. Or there could be 3 different element types - one Box, one Cylinder, one Cone.
Some background info about OSG to explain the source of my issue:
osg::Box and osg::Cylinder are both kinds of osg::Shape
both derived types have identical methods, getCenter
even though you can do osg::Shape myShape = osg::Box(); you can't then say myShape.getCenter(); - doesn't work on osg::Shape objects.
Here's an example of what I'm trying to do:
class MyClass {
private:
// ???? How to reference 'shape' ??
public:
MyClass(string _type) {
// This is for example purposes. Eventually types & mappings will be discovered at run-time.
if (_type == "FOO") {
shape = new osg::Box();
} else if (_type == "BAR") {
shape = new osg::Sphere();
}
}
/*
???? How to handle getShape()??
*/
}
int main() {
string readFromData = "FOO";
MyClass* myFoo (readFromData);
string alsoFromData = "BAR";
MyClass* myBar (alsoFromData);
osg::Vec3f fooCenter = myFoo->getShape()->getCenter();
osg::Vec3f barCenter = myBar->getShape()->getCenter();
}
I've tried a few different approaches but haven't quite been able to work it out:
creating a MyShape class that extends osg::Shape, and has a virtual function header for getCenter - but this makes MyShape an abstract class that cannot be instantiated.
template<typedef T> class MyClass... - but if we only discover the type & shape mappings at runtime, then what goes in the angle brackets throughout the rest of my code? e.g.: MyClass<?????????>* myFoo;
using boost::any to store the shape internally - but same issue basically. How do you define a getShape function that could return a pointer to one of several different types?
I can't find any previous questions that deal with this type of scenario specifically (sorry if I missed one!). If anyone can help me it'd be super awesome!
OSG supplies a osg::ShapeVisitor class for situations such as this one. Create a CenterFinderVisitor class that extends osg::ShapeVisitor, overriding each of its virtual member functions to retrieve the center of the corresponding shape. Pass an instance of the CenterFinderVisitor to the osg::ShapeVisitor's accept() member function on the shape instance that you store by pointer inside your class to retrieve the center, like this:
struct CenterFinderVisitor : public osg::ShapeVisitor {
Vec3 center;
virtual void apply (Sphere &s) { center = s.getCenter(); }
virtual void apply (Box &b){ center = b.getCenter(); }
// ...and so on for other shapes
};
Now you can implement your getCenter() method as follows:
class MyClass {
private:
osg::Shape *shape;
public:
MyClass(string _type) {
// This is for example purposes. Eventually types & mappings will be discovered at run-time.
if (_type == "FOO") {
shape = new osg::Box();
} else if (_type == "BAR") {
shape = new osg::Sphere();
}
}
Vec3 getShapeCenter() {
CenterFinderVisitor cf;
shape->accept(cf);
return cf.center;
}
};
If you are not familiar with the visitor pattern, read this article on wikipedia.
This is a classic OOP question.
Have shape base class and have all shapes inherit from it.
In shape declare all functions (pure virtual or just virtual) you want a shape to have:
class shape {
public:
shape(string _name) : name(_name) {}
virtual ~shape(); // virtual desructor
virtual POINT getCenter() = NULL;
virtual getName() { return name; } // example - functionality in base class
protected:
string name;
};
class rectangle : public shape {
{
rectangle() : shape("rectangle") {}
virtual POINT getCenter() { return /* do math here :) */ }
};
In your MyClass class, have a pointer/ref to a shape type.

How can I iterate over a vector of base class objects?

I have an problem where we need to have a number of shapes, such as a Circle and Square which can be position on a flat, 2 dimensional plane. All shapes, such as Circle and Square inherit from an abstact base class Shape; as such I have a vector of pointers to shapes.
However, I need to be able to iterate over the plane and find any shapes which collide, such that they are intersecting or touching. If I get a shape from the vector, I don't know if it is a Square or a Circle because it has been sliced to the Shape base class.
How would I be best solving this problem?
#ifndef Plane_h
#define Plane_h
#include <vector>
#include "Shape.h"
class Plane {
public:
Plane(std::vector<Shape*>);
Plane(const Plane&);
~Plane();
void add(Shape*);
std::vector<Shape*> all() const;
protected:
std::vector<Shape*> shapes;
};
#endif
Your classes have not been sliced. This would result in a sliced object:
vector<Shape> vec;
Circle circ;
vec.push_back(circ);
http://en.wikipedia.org/wiki/Object_slicing
In your instance the instantiated objects remain whole and the pointers point to whole objects - but it is almost certainly true that in order to calculate intersections you will need to do some downcasting. While this is to be done as little as possible it's not a crime in itself.
Your best bet would be to provide a method in the base class to return a value indicating the object type - maybe use an enumeration - and use that to downcast a particular Shape pointer or reference to a pointer/reference to the correct derived type.
An abstract method in the base Shape class like bool Intersects( const Shape& obj ) could be overridden by the derived classes, the overrides downcasting the parameter to the correct derived type.
Alternatively you might prefer to provide a global/static method taking two shapes, or privately implement that method and call it from the instance method Intersects()
( Detecting the intersections is not exactly a trivial task. :-) )
You have to use polymorphism. Add a virtual method on your Shape class:
class Shape {
...
virtual bool intersects(Shape const* otherShape);
...
}
Then you implement it for each different shape. Then if it's used like:
Shape* A = getShapeA();
Shape* B = getShapeB();
if (A->intersects(B))
doSomething();
The correct version is called, i.e if A is a Circle, Circle::intersects is called. But in there, you still don't know what shape B actually is. You can find this out by trying to do a dynamic cast:
Circle* circle = dynamic_cast<Circle*>(otherShape);
if (circle)
intersectsCircle(circle);
Here is another method, that does not need dynamic casts (or any explicit cast at all), or an ugly enum listing the subclasses. It is based on double dispatch, which basically works by going through two virtual methods in order to determine the types of the two objects you want to work on.
#include <iostream>
using namespace std;
class Circle;
class Square;
struct Shape
{
virtual void intersect(Shape* otherShape) = 0;
virtual void intersect(Circle* otherCircle) = 0;
virtual void intersect(Square* otherSquare) = 0;
};
struct Circle : public Shape
{
virtual void intersect(Shape* otherShape)
{
otherShape->intersect(this);
}
virtual void intersect(Circle* otherCircle)
{
cout << "Intersecting Circle with Circle" << endl;
}
virtual void intersect(Square* otherSquare)
{
cout << "Intersecting Circle with Square" << endl;
}
};
struct Square : public Shape
{
virtual void intersect(Shape* otherShape)
{
otherShape->intersect(this);
}
virtual void intersect(Circle* otherCircle)
{
otherCircle->intersect(this);
}
virtual void intersect(Square* otherSquare)
{
cout << "Intersecting Square with Square" << endl;
}
};
int main()
{
Circle circle;
Square square;
circle.intersect(&square);
Shape* shapeA = &circle;
Shape* shapeB = &square;
shapeA->intersect(shapeA);
shapeA->intersect(shapeB);
shapeB->intersect(shapeA);
shapeB->intersect(shapeB);
}
Note that here you still have to list all possible subclasses within the base class, but in this case in the form of overloads of the intersect for each base class. If you fail to add all (say, you make a class Triangle : public Shape, but no Shape::intersect(Triangle*)), you end up with infinite call loops.
Also note that in this example I did a 'triple' dispatch, so I don't have to implement the logic to intersect a Circle with a Square twice.

Determining which derived class the pointer to the abstract class is set to

I'm not sure if I phrased my question as well as I liked to but I'll give an example to clear things up.
Here is the code:
class Shape;
class Circle;
class Triangle;
class Shape
{
Shape(void);
~Shape(void);
virtual void DrawShape(void) = 0;
}
class Circle : public Shape
{
/* .... constructor/destructor defined normally .... */
bool TestIntersection(Triangle* _triangle);
bool TestIntersection(Circle* _circle);
void DrawShape(void);
}
/* main.cpp */
...
Shape* shape;
Shape* circle = new Circle;
if(a == 0)
{
shape = new Circle;
}
else
{
shape = new Triangle;
}
circle->TestIntersection(shape);
I get the error that there is no acceptable conversion from Shape* to Circle* or Triangle*.
Why is this happening? Or do I need a way to determine which derived class has been set to the abstract class pointer?
What you need basically is this:
Visitor pattern
I noticed that you have not derived your supposedly derived classes from Shape. Fix that also. That is, Triangle and Circle should be derived from Shape. After that, read about Visitor pattern, its various implementations and usage. That will help you in solving your problem.
This is happening because you have actually not derived from the Shape.
class Circle: public Shape {
...
};
Your Circle class doesn't seem to inherit from Shape:
Try this:
class Circle : Shape
{
}