Better solution than dynamic_cast in C ++

I have a class hierarchy that I developed for my project, but I'm not sure how to implement part of it.

Here is the class hierarchy:

class Shape { };

class Colored { // Only pure virtual functions
};

class Square : public Shape { };

class Circle : public Shape { };

class ColoredSquare : public Square, public Colored { };

class ColoredCircle : public Circle, public Colored { };

As part of my project, I have std :: vector of various types. However, in order to run the algorithm, I need to put them in std :: vector of colored objects (all of which are derived types of various concrete shapes, so I need a method to drop a square in ColororedSquare and Circle in ColoredCircle at runtime. that the “shape” classes are in a different library than the “color” classes. What is the best method for this? I was thinking of doing a dynamic_cast check, but if there is a better way, I'd rather go with that.

Change 1:

Here is a little better Example:

class Traceable {
    public:
        // All virtual functions
        virtual bool intersect(const Ray& r) = 0;
        // ...
};

class TraceableSphere : public Sphere, public Traceable {
};

class IO {
    public:
        // Reads shapes from a file, constructs new concrete shapes, and returns them to
        // whatever class needs them.
        std::vector<Shape*> shape_reader(std::string file_name);
};

class RayTracer {
    public:
        void init(const std::vector<Shape*>& shapes);
        void run();
    private:
        std::vector<Traceable*> traceable_shapes;
};

void RayTracer::init(const std::vector<Shape*>& shapes) {
    // ??? traceable_shapes <- shapes
}

void RayTracer::run() {
    // Do algorithm
}
+4
5

:

class ColorDecorator public Colored
{
    ColorDecorator(Shape* shape): m_shape(shape) {}
    ... //forward/implement whatever you want
};

, .

, , . , (aka double dispatch), , - .

+4

, "is-a", Inheritance-Hell. ""? , , " " , , . , , (design-pattern: "strategy" ), " ".

+1

casting. , SRP. , Interface / . , . :

class A {
  public:
        void doSomeThing();
};

class B{
  public:
        void doSomeOtherThing();
};

class C:public A,public B{};

void f1( A* a){
   //some operation
   a->doSomeThing();
   //more operation
}
void f2(B* b){
   //some operation
   b->doSomeOtherThing();
   //more operation

}

int main(int argc, char* argv[])
{
  C c;
  f1(&c);
  f2(&c);

  return 0;
}

, c . , Interface of c, . f f2. , Algorithm, , , , , / instance .

0

- , -. - . , , . - , , ++, .

dynamic_cast - - , . - ( , ), , , - virtual Concrete* ToConcrete() .

0

, , , .

class Shape {
  virtual Colored *getColored() {
    return NULL;
  }
};

class Colored { // Only pure virtual functions
};

class Square : public Shape { };

class Circle : public Shape { };

class ColoredSquare : public Square, public Colored {
  virtual Colored *getColored() {
    return this;
  }
};

class ColoredCircle : public Circle, public Colored {
  virtual Colored *getColored() {
    return this;
  }
};

, " , " shape " , " ".

How does this not allow you to do what is proposed here (but still allows you to create the ColoredSquare class)?

0
source

Source: https://habr.com/ru/post/1539944/


All Articles