C ++ class design with multiple interfaces for each individual behavior

This is my first post, so be kind. This is a question from an interview I recently received, but I could not find the answer after the search (Google, C ++ FAQ, etc.).

There is an I1 interface with the behavior of b1 (). There are 3 classes A, B, C. All of these classes implement the I1 interface, overriding b1 (). There is a fourth class D, which has behavior (b1) defined in interface I1, and additional behavior b2

Question: how do you create class D.

My answer was to create another I2 interface that defines the behavior of b2 () and makes class D implement I1 and I2 (multiple inheritance in C ++) by overriding both b1 () and b2 ()

The interviewer agreed with the decision, but asked that if new classes with a new set of behaviors appear in the future, how will we deal with this

I could only think of adding additional interfaces (I3, I4, etc.) and performing multiple inheritance, but I know that here you get into a huge number of derived classes with corresponding interfaces

The interviewer seemed to be expecting a better solution, but he did not disclose the answer. I would be interested to know how experts will solve this design problem.

PS: After thinking seriously about this, I think the answer may be to use a design pattern, but looking at the general design patterns, I could not find a single one that would fit this problem.

edit 1: , , , , .

@Nawaz, @Alexandre @Sjoerd . ++/design, .

Vistor by @Nawaz , , , . @Alexandre .

. ,

1) , . ( ) : ( @Nawaz) - , , , ..

2) , ( ) : , , ( , )

3) . , , - .

, , 1), , 2) 3).

IDude, , Dude, .

    class IComposerBehavior;

    class IComposer
    {
       public:
          virtual ~IComposer() {}
          virtual void accept(IComposerBehavior *behaviour) = 0 ;
    };

    class IComposerBehavior
    {
       public:
          virtual ~IComposerBehavior() {}
          virtual void visit(IComposer * ) = 0;
    };

    class Dude : public IDude, public IComposer
    {
        public:
          virtual void accept(IDudeBehavior *behaviour)
          {
              behaviour->visit(this);
          }
          virtual void accept(IComposerBehavior *behaviour)
          {
              behaviour->visit(this);
          }
    };

    class SymphonyComposerBehavior : public IComposerBehavior
    {
      public:
         virtual void visit(IComposer *dude) { cout << "Dude is composing a symphony" << endl;   }
    };

SymphonyComposerBehavior.

, Dude , .

, , , . , , , , @Alexandre?

( , ). , - Robot. ,

- Initially We are only producing Toy Robots
- Then Human helper Robots
- Then Self Healing Robots (would just correct itself when defective)
- Then Humanoid Robots
- Then machine Robots (that are not human like but as a substitute for any machine you can think of) . I have deliberately put this here even though its place should be before with a correct evolution scheme.
- finally Humanoid Robots with life (atleast we can dream :-) )

, , , , . , , , (, , ), ?

.

+5
2

, , .

, / / . , , .

; :

:

class IDudeBehavior;

class IDude
{
   public:
      virtual ~IDude() {}
      virtual void accept(IDudeBehavior *behaviour) = 0 ;
};

class IDudeBehavior
{
   public:
      virtual ~IDudeBehavior() {}
      virtual void visit(IDude * ) = 0;
};

class Dude : public IDude
{
    public:
      virtual void accept(IDudeBehavior *behaviour)
      {
          behaviour->visit(this);
      }
};

class LaughDudeBehavior : public IDudeBehavior
{
  public:
     virtual void visit(IDude *dude) { cout << "Dude is Laughing" << endl; }
};

class WalkDudeBehavior : public IDudeBehavior
{
  public:
     virtual void visit(IDude *dude) { cout << "Dude is Walking" << endl; }
};
int main() {
        IDude *dude = new Dude();
        dude->accept(new LaughDudeBehavior());
        dude->accept(new WalkDudeBehavior());
        return 0;
}

- : http://ideone.com/Kqqdt

Dude , LaughDudeBehavior WalkDudeBehavior, Dude, Dude. , EatDudeBehavior StudyCplusCplusDudeBehavior, IDudeBehavior :

class EatDudeBehavior : public IDudeBehavior
{
  public:
     virtual void visit(IDude *dude) { cout << "Dude is Eating" << endl; }
};

class StudyCplusCplusDudeBehavior : public IDudeBehavior
{
  public:
     virtual void visit(IDude *dude) { cout << "Dude is Studying C++" << endl; }
};

:

dude->accept(new EatDudeBehavior ()); 
dude->accept(new StudyCplusCplusDudeBehavior ());

: http://ideone.com/9jdEv


. , , . new, delete. .

​​ :

int main() {
        IDude *dude = new Dude();

        std::vector<IDudeBehavior*>  behaviours;
        behaviours.push_back(new LaughDudeBehavior());
        behaviours.push_back(new WalkDudeBehavior());
        behaviours.push_back(new EatDudeBehavior());
        behaviours.push_back(new StudyCplusCplusDudeBehavior());

        for(size_t i = 0 ; i < behaviours.size() ; i++ )
           dude->accept(behaviours[i]);

        //deallcation of memory!
        for(size_t i = 0 ; i < behaviours.size() ; i++ )
           delete behaviours[i];
        delete dude;
        return 0;
}

.:-)

+6

(...)

. . .


, , : . Visitor - ( ) , .

Visitor , (.. , ), dynamic_cast , . . dynamic_cast.

Visitor ( dynamic_cast, ) , , , . , , , .


, , , - . . , , , .

. , .

. .


? , . , , , .

. n (, , deque, set ..) m (find_if, count, copy, for_each ..).

: , O (nm). , ( , []), : , . O (n + m).


, , , . : .

, , , Visitor.

: .

+2

All Articles