Reputation: 1666
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
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
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