MGA
MGA

Reputation: 1666

Multiple Interfaces to a Class in C++

I have three classes that interact as follows. Class A contains a private member of type Class B. It also contains a method to which an object of type ClassC is passed. This method then calls a method on ClassC, passing to it a particular interface (ClassBInterface1) of its member of type ClassB:

 ClassA
 {
     void Foo(ClassC ObjectC)
     {
         ObjectC.Bar((ClassBInterface1) ObjectB);
     }
     ClassB ObjectB;
 }

My question is: ClassA does not need to access the methods of ClassB defined in Interface1. Therefore, in my view, it would be more elegant if the member of ClassA was of type ClassBInterface2, rather than ClassB. Is it possible to do this, while still passing B to C under Interface1?

The only way I can think of is to typecast ClassBInterface2 to ClassB and back to ClassBInterface1 in the Bar method in ClassA.

Is this the best way to do it? Or should I just leave it as it is?

Thanks a lot for any help.

Upvotes: 0

Views: 415

Answers (2)

Ryan Calhoun
Ryan Calhoun

Reputation: 2363

C++ has a great feature for this called "forward declarations". Basically, for any parts of your code that don't need to know the details of a class, you can simply pass around a reference. Only when you want to call member methods (including constructors and destructors) do you need to have the full class definition.

#include "ClassC.h"
class ClassB;

class ClassA
{
public:
    void foo(ClassC& objectC)
    {
       objectC.bar(_objectB);
    }

protected:
    ClassB& _objectB;
};

Note that we include a header for ClassC because we need to call one of his methods.

Note that we forward declare ClassB and only hold a reference because we don't really care what he is.

Note finally that ClassA can't be instantiated currently, because somehow the reference to _objectB has to be set to something. For example, a constructor:

public ClassA(ClassB& objectB)
    : _objectB(objectB)
{}

ClassA now only holds on to whatever reference was given to him on construction.

Based on your use of the term "interface" in your question, I assume you may have a class hierarchy. This answer can easily be extended to such a hierarchy. But the important point here is that concrete types always require a class definition, while simple reference object only require a forward declaration.

Upvotes: 0

ibesora
ibesora

Reputation: 307

If you define ObjectB as a ClassBInterface2 it won't be possible to convert it to ClassBInterface1 at runtime because it's internal structure won't be known.

Your way is the best one to do it but you can do a little modification. You don't need to do a explicit cast from ClassB to ClassBInterface1 while calling ObjectC.Bar because the compiler will do it for you.

If class B is defined as follows:

ClassB : public ClassBInterface1, ClassBInterface2
{

  /*Class methods and attributes*/

}

you can just do the following while calling the Bar function on the ObjectC (assuming objectB is defined as ClassB)

ObjectC.Bar(ObjectB);

Upvotes: 3

Related Questions