Inheritance depth, Single responsability or DRY - c++

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.

Related

Every abstract classes knows others

I'm having trouble to clearly visualize my idea in words. Below example may explain my thinking. I've two abstract class and two Derived class,
class Base1{
public:
virtual void f1() = 0;
std::string get(){ return "HelloWorld";}
};
class Derived1: public Base1{
public:
void f1() {}
void update (std::string& update){
**should call like** Base2::Derived2::update_data(this);}
};
=> and
class Base2{
public:
virtual void f2 () = 0;
};
class Derived2: public Base2{
public:
void f2() {}
void get (Base1& d1){ d1.Base1::get (); }
void update_data (Base1& d1){ d1.Base1::get (); }
};
=> the classes are called as
int main(){
Derived1 d1;
Derived2 d2;
d2.get (d1);
std::string hi = "hiWorld";
d1.update (hi);
return 0;
}
How can I achieve the **should call like** without passing the Base2 instance in d1.update ().
Another question is, what does it called, when each class objects knows other objects?
Thanks.
It seems like you need a technique called double-dispatch. C++ only directly supports single-dispatch - the behavior you get is only based on a single instance.
a->virtualFunction( params ); // exactly which implementation is called depends on the concrete type of a.
For double dispatch, (which does not exist), you would need something like
(a,b)->virtualFunction( params ); // where the call is based on both parameters.
There are some solutions to the problem. These require work where one type requires the knowledge of the other, but only that way round.
Consider a set of geometric shapes which we want to draw on surfaces.
class Surface;
class Drawable {
public:
virtual ~Drawable () {}
virtual void draw( Surface * ) = 0;
};
class Surface {
public:
virtual ~Surface () {}
// details ommitted.
}
class Rectangle : public Drawable {
};
class Circle : public Drawable {
}
// and some surfaces
class PrinterSurface : public Surface {
};
class PlotterSurface : public Surface {
};
The code we actually want to call, is dependent on both the surface and the shape.
To solve this, we choose one of the hierarchies which is most bounded, and tell the other hierarchy about the concrete instances of the type.
In this example, it is considered that more shapes and drawable objects will exist than technologies for rendering them.
So each drawable item will know how to draw on each of the surfaces.
class Drawable {
public:
virtual ~Drawable () {}
virtual void drawPrinter( Surface * ) = 0;
virtual void drawPlotter( Surface * ) = 0;
virtual void drawSurface( Surface * ) = 0;
};
class Surface {
public:
virtual ~Surface () {}
virtual void draw( Drawable * pDrawable ) = 0;
}
class PrinterSurface : public Surface {
void draw( Drawable * pDrawable ) {
pDrawable->drawPrinter( this );
}
};
Now a call to Surface->draw( Drawable *) will be bounced into a concrete implementation, where each Drawable understands how to render onto a device, but the devices have no knowledge of the gamut of Drawables
For further reading : wikipedia : double dispatch for a more full description.
and I would recommend the design patterns book wikipedia : design patterns
The design patterns give some idea of a vocabulary of design which make asking this form of question much easier.

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

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.

Adding class functionality via composition

Suppose we have an abstract class Element from which classes Triangle and Quadrilateral are derived from.
Suppose yet that these classes are used in conjunction with interpolation methods that depend on the shape of the element. So, basically we create an abstract class InterpolationElement from which we derive InterpolationTriangle and InterpolationQuadrilateral.
Then, to include the interpolation functionality in the Triangle and Quadrilateral classes, we add a const-reference data member in class Element of type InterpolationElement, that is:
class Element
{
public:
Element(const InterpolationElement& interp);
const InterpolationElement& getInterpolation() const;
private:
const InterpolationElement& interpolation;
};
We then create a method (as described by Scott Meyers, Effective C++) that instanciate a local static object of class InterpolationTriangle as
const InterpolationTriangle& getInterpolationTriangle()
{
static InterpolationTriangle interpolationTriangle;
return interpolationTriangle;
}
So that class Triangle can be constructed like:
class Triangle : public Element
{
public:
Triangle() : Element( getInterpolationTriangle() ) {}
};
Here is my question: is this approach correct in order to incorporate interpolation methods on my class Element? Is this used in professional scenarios?
I could implement directly all the interpolation methods on class Element (as pure virtual) and the override them in the derived classes Triangle and Quadrilateral. However, this approach seems to me to be cumbersome, since every time I need to improve or implement new interpolation functionalities I would have to do that on these classes. Moreover, the classes get bigger and bigger (many methods) using this approach.
I would like to hear from you some tips and comments
Thanks in advance.
Additional details:
class InterpolationElement
{
public:
InterpolationElement();
virtual double interpolationMethod1(...) = 0;
:
virtual double interpolationMethodN(...) = 0;
}
class InterpolationTriangle : public InterpolationElement
{
public:
InterpolationTriangle () {}
virtual double interpolationMethod1(...) { // interpolation for triangle }
:
virtual double interpolationMethodN(...) { // interpolation for triangle }
}
class InterpolationQuadrilateral : public InterpolationElement
{
public:
InterpolationTriangle () {}
virtual double interpolationMethod1(...) { // interpolation for quadrilateral}
:
virtual double interpolationMethod1(...) { // interpolation for quadrilateral}
}
The classes are used in conjunction with interpolation methods. Why do those methods need to be in a singleton object? The singleton here looks very problematic.
class Element
{
public:
virtual double interpolationMethod1(...) = 0;
:
virtual double interpolationMethodN(...) = 0;
};
class Triangle : public Element
{
public:
virtual double interpolationMethod1(...) { // interpolation for triangle }
:
virtual double interpolationMethodN(...) { // interpolation for triangle }
}
Also, welcome to SO!
This is reminiscent of a question that I had answered here. The same idea about the separation of data containers and the strategies.
There is one little issue with your proposal: you have added an interpolation related method to your base class and you've changed the constructor...
So first of all, if you wish to do it this way, here is how you should do it:
class Element
{
public:
private:
// similar signature to a `clone` method
virtual InterpolationElement* interpolation() const = 0;
};
class Triangle
{
public:
private:
virtual InterpolationTriangle* interpolation() const
{
return new InterpolationTriangle();
}
};
There are 2 advantages here:
It's no longer necessary to change the constructor of each of the derived objects
The strategy object is no longer const, which allows it to maintain state during the computation... like a reference to the current object being interpolated.
However, this still requires to change the Element class, and each of its derived classes. Doesn't it bother you ;) ?
Well, it's time (for once) to call upon a Design Pattern: Visitor.
It's a little different from the strategy idea, relying on double dispatch to work properly. However it allows you to tweak the hierarchy of Elements ONCE (with an accept method) and then to add as many operations as you wish. And that is great.
You can always mess a little bit with templates.
First we have a top class.
class Element {
public:
virtual void calculate() const = 0;
};
... but then we also have a class in the middle of the hierarchy which is actually a template. Template can't be the top level class, as templates with different parameters are different classes. The idea is that we give an interpolation class as a type parameter to the element.
template <typename Interpolation>
class Element_Impl : public Element {
protected:
Interpolation m_interpolation;
};
And interpolation classes. Notice, they aren't siblings, because they don't need to.
class InterpolationTriangle {
public:
double interpolate(double a, double b) const {
std::cout << "interpolation triangle" << std::endl;
}
};
class InterpolationQuadrilateral {
public:
double interpolate(double a, double b) const {
std::cout << "interpolation quadrilateral" << std::endl;
}
};
And finally the real elements and the small main procedure.
class Triangle : public Element_Impl<InterpolationTriangle> {
public:
void calculate() const {
m_interpolation.interpolate(1.0, 2.0);
}
};
class Quadrilateral : public Element_Impl<InterpolationQuadrilateral> {
public:
void calculate() const {
m_interpolation.interpolate(2.0, 3.0);
}
};
int main() {
const Element &a = Triangle();
const Element &b = Quadrilateral();
a.calculate();
b.calculate();
}
Summary:
you can easily switch interpolation class for each element if needed.
there aren't double vtable access (first for Element's calculate and then for InterpolationElement's intepolate methods) as in the Matthieu's example. Each element knows at compile time which interpolation class it is using.
Element_Impl is an ugly bit, but it saves us from copypasta. You can expand it even further by implementing interpolation method wrappers
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
One way is to use static methods, and defining a wrapper in Element_Impl - still only in one place.
class Element {
public:
virtual void calculate() const = 0;
};
template <typename Interpolation>
class Element_Impl : public Element {
protected:
void interpolate(double, double) const {
Interpolation::interpolate(1, 1);
}
};
class InterpolationTriangle {
public:
static double interpolate(double a, double b) {
std::cout << "interpolation triangle" << std::endl;
}
};
class InterpolationQuadrilateral {
public:
static double interpolate(double a, double b) {
std::cout << "interpolation quadrilateral" << std::endl;
}
};
class Triangle : public Element_Impl<InterpolationTriangle> {
public:
void calculate() const {
interpolate(1.0, 2.0);
}
};
class Quadrilateral : public Element_Impl<InterpolationQuadrilateral> {
public:
void calculate() const {
interpolate(2.0, 3.0);
}
};
int main() {
const Element &a = Triangle();
const Element &b = Quadrilateral();
a.calculate();
b.calculate();
}
What first comes to my mind is the GoF Design Pattern Visitor
From what I understand of your problem, this pattern is conceived to exactly solve this issue.
Each Visitor object defines an interpolation technique, or an algorithm to apply to your object.
Thus the Element class doesn't grow at all with each new functionnality. Once in place, the Visitor pattern enables to enrich functionnality without touching to the Base class definition.

C++ How to I replace this if...else statement?

I have the following C++ code (simplified version):
class Shape
{
bool isCircle = false;
bool isSquare = false;
}
class Circle : public Shape
{
// some special members/methods
}
class Square : public Shape
{
// some special members/methods
}
class CAD
{
virtual DrawCircle(Circle * circle) = 0;
}
class SWX : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on SWX system}
}
class PRO : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on PRO system}
}
int main()
{
Circle * circle = new Circle();
circle->isCircle = true;
Square * sq = new Square;
sq->isSquare = true;
vector<Shape*> shapes;
shapes.push_back(circle);
shapes.push_back(sq);
SWX * swx = new SWX();
for( int i = 0 ; i < shapes.size() ; ++i )
{
if( shapes[i]->isCircle )
{
SWX->DrawCircle((Circle*)(shapes[i]));
}
else if( shapes[i]->isSquare )
{
SWX->DrawSquare((Square*)(shapes[i]));
}
}
I wish to remove the need for if...else (if at all possible within the constraints stated below).
My constraints right now are:
The CAD and derived classes are ginormous classes with various external dependencies.
The CAD classes cannot be merged with the Shape and derived classes (that would have been ideal, since then I can use polymorphism to solve my problem), since other projects/classes depend on the Shape classes and cannot depend on the CAD classes.
There are more than a dozen Shape-derived classes with a half dozen CAD-derived classes and this if...else is happening in numerous locations - so it would help if any solution is simple to understand (easier to convince my teammates to change legacy code).
Any suggestions/comments/solution you have would be most welcome.
The standard solution for this problem, especially given your constraints regarding dependencies, is to use the Visitor Pattern.
Here's how Visitor Pattern would work in your case:
You need an abstract ShapeVisitor class. It has an abstract Visit method for each concrete subclass of Shape. eg: Visit(Circle*), Visit(Square*), etc.
Shape has an abstract AcceptVisitor(ShapeVisitor*) method.
Each Shape subclass implements AcceptVisitor as just calling visitor->Visit(this)
Each CAD class is a (or has-a, up to you) a ShapeVisitor. The Visit methods do the appropriate drawing for the specific type of Shape. No conditional or casting required.
Here's a modified version of your code that uses Visitor Pattern in a pretty low-impact way:
class Circle;
class Square;
class ShapeVisitor
{
virtual void Visit(Circle *circle) = 0;
virtual void Visit(Square *square) = 0;
}
class Shape
{
virtual void AcceptVisitor(ShapeVisitor *visitor) = 0;
}
class Circle : public Shape
{
// some special members/methods
virtual void AcceptVisitor(ShapeVisitor *visitor)
{
visitor->Visit(this);
}
}
class Square : public Shape
{
// some special members/methods
virtual void AcceptVisitor(ShapeVisitor *visitor)
{
visitor->Visit(this);
}
}
class CAD : public ShapeVisitor
{
virtual DrawCircle(Circle *circle) = 0;
virtual DrawSquare(Square *square) = 0;
virtual void Visit(Circle *circle) {
DrawCircle(circle);
}
virtual void Visit(Square *square) {
DrawSquare(square);
}
}
class SWX : public CAD
{
virtual DrawCircle(Circle *circle){// do some stuff that draws circle on SWX system}
}
class PRO : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on PRO system}
}
int main()
{
Circle * circle = new Circle();
Square * sq = new Square;
vector<Shape*> shapes;
shapes.push_back(circle);
shapes.push_back(sq);
SWX * swx = new SWX();
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->AcceptVisitor(SWX);
}
}
In this code I've opted for making CAD actually a subclass of ShapeVisitor. Also, since you've already got virtual methods in CAD to do the drawing, I implemented the Visit methods there (once), rather than once in each subclass. Once you switch clients over to the using AcceptVisitor instead of calling the Draw* methods directly you could make those methods protected, and then eventually move the implementation of the Visit methods down to the subclasses (that is: refactor to remove the extra level of indirection caused by having Visit(Foo*) call DrawFoo(Foo*)).
This is a classic case for DoubleDispatch, where you need to have a separate method for each possible (Shape, CAD) pair:
Nuke the isSquare/isCircle fields.
add virtual void DrawOn(CAD*) to the Shape interface.
Implement Circle::DrawOn(CAD*) (for example):
void Circle::DrawOn(CAD *c) {
c->DrawCircle(this);
}
This is the "trick" which allows a call like myCircle->DrawOn(mySWX) to call the correct method no matter the type of the Shape or the CAD.
You've got some rather wonky OO going on there, but at the very least DrawXxxx should just become Draw(). Circle, Square, and the other shapes would then define a Draw() method that provides an implementation for a virtual Draw method on Shape. Then you can just call Draw on any Shape and it will do the right thing.
The isXxxx booleans should go too. Classes know what they are and instanceof can tell you (though it shouldn't be necessary to check when you Draw since that will be a virtual method invocation).
Why not just SWX->Draw(shapes[i]);? You would need to add two Draw method with one that takes a Circle and one that takes a square?
This is pretty basic OO polymorphism. Circle and Square are specialized versions of shape. They should each know what specialized behavior is needed to deal with your cad classes.
class Shape
{
virtual void DrawWithCAD(CAD * cad) = 0;
}
class Circle : public Shape
{
virtual void DrawWithCAD(CAD * cad)
{
cad->DrawCircle(this);
}
}
class Square : public Shape
{
virtual void DrawWithCAD(CAD * cad)
{
cad->DrawSquare(this);
}
}
Then your main() loop would change to:
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->DrawWithCAD(swx);
}
Why not define a simple ICAD interface? Since CAD depends on Shape it does not increase complexity:
class Shape
{
Draw(ICAD* cad) = 0;
}
class Circle : public Shape
{
Draw(ICAD* cad)
{
ICAD->DrawCircle(self)
}
}
class Square : public Shape
{
Draw(ICAD* cad)
{
ICAD->DrawSquare(self)
}
}
DrawSquare(self) looks funny, but I don't know what the CAD classes do with the shape objects.
class ICAD
{
virtual DrawSquare(Square* square) = 0;
virtual DrawCircle(Circle * circle) = 0;
}
I assume class CAD has more than those abstract methods, which is why you don't couple it with Shape.
class CAD : public ICAD
{
// big CAD class...
}
class SWX : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on SWX system}
}
class PRO : public CAD
{
virtual DrawCircle(Circle * circle){// do some stuff that draws circle on PRO system}
}
int main()
{
Circle * circle = new Circle();
Square * sq = new Square;
vector<Shape*> shapes;
shapes.push_back(circle);
shapes.push_back(sq);
SWX * swx = new SWX();
for( int i = 0 ; i < shapes.size() ; ++i )
{
shapes[i]->Draw(swx);
}
}
This may not be the ideal solution, but you could just provide an CAD::Draw member function and overload it to handle each different type of shape. Something like:
class CAD {
public:
virtual void Draw(const Circle& circle) = 0;
virtual void Draw(const Square& square) = 0;
};
Then you could just call Draw on any supported object without any if statements.
Write a several global Draw functions overloaded for each Shape... (DrawCircle and friends are virtual so we can use polymorphism for calls to CAD objects)
void Draw(CAD *cad, Circle *circle){
cad->DrawCircle(circle);
}
void Draw(CAD *cad, Square *square){
cad->DrawSquare(square);
}

Multiple inheritance in C++ leading to difficulty overriding common functionality

In a C++ physics simulation, I have a class called Circle, and Square. These are Shapes, and have a method called push(), which applies force to it. There is then a special case of Circle, call it SpecialCircle, in which push() should exhibit slightly different properties. But in fact, there is also SpecialSquare() which should exhibit the same force properties. So I'd like to have an abstract base class called Shape which takes care of Circles and Squares, but then I'd also like an abstract base class called Special, which applies special properties to force().
What's the best way to design this class structure?
So far, I've got:
class Shape {
virtual void push();
};
class Circle : public Shape {};
class Square : public Shape {};
class Special {
virtual void push();
};
class SpecialCircle : public Circle, Special {};
class SpecialSquare : public Square, Special {};
Of course, the above won't compile, since Special::push() and Shape::push() conflict. I get "error: request for member ‘push’ is ambiguous", as expected.
How can I re-organize my class structure so that Circle and Square can share certain properties with each other, but SpecialCircle and SpecialSquare can still inherit from Shape, and also inherit modified functionality from Special?
Thanks.
ps., is this the diamond inheritance problem?
Another solution (it may or may not fit your needs, it depends on the details of your implementation):
Have the class Behavior, and let NormalBehavior and SpecialBehavior inherit from it.
Have the class Shape, and let Square and Circle inherit from it. Let Shape be an aggregate type, with a Behavior member (i.e. you pass a Behavior object to the various Shape constructors). In other words, let a Shape have a Behavior.
Delegate the actual differences in the behavior of shapes to methods of the Behavior hierarchy.
Conversely, you can:
Have the class PhysicalObject, and let NormalObject and SpecialObject inherit from it;
Have the class Shape, and let Square and Circle inherit from it;
Let a PhysicalObject have a Shape.
Prefer aggregation over inheritance. This is an application of the Bridge pattern. The advantage of this strategy with respect to having Square, SpecialSquare, Circle, and SpecialCircle, is that tomorrow you'll have to add Rectangle, Hexagon and so on, and for each shape you add you'll have to implement two classes (duplicated code is evil); this is, in my opinion, the real issue that Bridge addresses.
It's said that every problem in software can be solved by adding an additional layer of indirection.
Herb Sutter has an excellent article on how to solve your problem: Multiple Inheritance - Part III
In short, you use intermediate classes to 'rename' the virtual functions. As Herb says:
Renaming Virtual Functions
If the two inherited functions had different signatures, there would be no problem: We would just override them independently as usual. The trick, then, is to somehow change the signature of at least one of the two inherited functions.
The way to change a base class function's signature is to create an intermediate class which derives from the base class, declares a new virtual function, and overrides the inherited version to call the new function
Here's a long example using your classes:
class Shape {
public:
virtual void push() = 0;
};
class Circle : public Shape
{
public:
void push() {
printf( "Circle::push()\n");
}
};
class Square : public Shape
{
public:
void push() {
printf( "Square::push()\n");
}
};
class Special {
public:
virtual void push() = 0;
};
class Circle2: public Circle
{
public:
virtual void pushCircle() = 0;
void push() {
pushCircle();
}
};
class Square2: public Square
{
public:
virtual void pushSquare() = 0;
void push() {
pushSquare();
}
};
class Special2 : public Special
{
public:
virtual void pushSpecial() = 0;
void push() {
pushSpecial();
}
};
class SpecialCircle : public Circle2, public Special2
{
public:
void pushSpecial() {
printf( "SpecialCircle::pushSpecial()\n");
}
void pushCircle() {
printf( "SpecialCircle::pushCircle()\n");
}
};
class SpecialSquare : public Square2, public Special2
{
public:
void pushSpecial() {
printf( "SpecialSquare::pushSpecial()\n");
}
void pushSquare() {
printf( "SpecialSquare::pushSquare()\n");
}
};
int main( int argc, char* argv[])
{
SpecialCircle sc;
SpecialSquare ss;
// sc.push(); // can't be called - ambiguous
// ss.push();
sc.pushCircle();
ss.pushSquare();
Circle* pCircle = &sc;
pCircle->push();
Square* pSquare = &ss;
pSquare->push();
Special* pSpecial = &sc;
pSpecial->push();
pSpecial = &ss;
pSpecial->push();
return 0;
}
Rather than thinking of code reuse through inheritance, the use of mixins will give you the code reuse you want without the problems of multiple inheritance.
If you are unfamiliar with the technique, do a search on SO or Google. Make sure you search for both "mixin" and "Curiously Recurring Template Pattern". There are heaps of great articles around to get you started.
When you have to inherit from multiple interfaces with the same method the compiler can't tell which one are you trying to call, you can fix this by overriding such method and call the one you want.
class SpecialCircle : public Circle, Special {
public:
virtual void push() { Special::push(); }
};
class SpecialSquare : public Square, Special {
public:
virtual void push() { Special::push(); }
};
But in this case I think the correct OO approach is to factor out the push behavior in its own class, like Federico Ramponi have suggested.
Have a SpecialShape from Shape and SpecialCircle and SpecialSquare from SpecialShape.
Well, if the special and normal circles can be both applied forces to, and the special circle has another method that applies special forces, why not have two interfaces and two methods?
struct Applicable {
virtual ~Applicable() { }
// if it applies force, better be explicit with naming it.
virtual void applyForce() = 0;
};
struct SpecialApplicable {
virtual ~SpecialApplicable() { }
virtual void applySpecialForce() = 0;
};
struct Shape {
virtual ~Shape() { }
Size getSize();
Point getPosition();
// ...
};
struct Circle : Shape, Applicable {
virtual void applyForce() { /* ... */ }
}
struct SpecialCircle : Circle, SpecialApplicable {
virtual void applySpecialForce() { /* .... */ }
};
If it doesn't make sense if there is both a special and a normal apply method (which the name of the class - SpecialCircle - suggests), then why not do even this:
struct Circle : Shape, Applicable {
virtual void applyForce() { /* ... */ }
}
struct SpecialCircle : Circle {
// applies force, but specially
virtual void applyForce() { /* .... */ }
};
You can also put the applyForce into the Shape class. It also depends on the environment in which those classes are used. What, in any case, you really should avoid is having the same method in two base classes that appear in two difference base-lattices. Because that inevitable will lead to such ambiguity problems. The diamond inheritance is when you use virtual inheritance. I believe there are other good answers on stackoverflow explaining that. It isn't applicable for your problem, because the ambiguity arises because the method appears in two base class sub-objects of different types. (It only solves such cases where the base classes have the same type. In those cases, it will merge the base classes and there will only be one base class sub-object contained - inherited by virtual inheritance)