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.
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);
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.
Related
I am working with a GitHub library and ran across a derived class instantiation that perplexes me. In abbreviated form,
class A
{
public:
A() {}
int AFunc(void) { return(1); }
};
class B : public A
{
public:
B(void) : A() {}
int BFunc(void) { return(2); }
};
Within an include file, the class is instantiated as follows:
A &tObject = *(new B());
Sample code then refers to 'tObject' as global variable calling methods from class A and/or B.
For example:
tObject.AFunc();
tObject.BFunc();
So here's the question, is that instantiation legal?
The compiler is only fussing on the call to a service class's method, saying that class A has no such member. That error makes sense to me and I've narrowed the issue to the above explanation.
While I do not have broad compiler experience, I have been programming in C++ for many years. I've never seen such a construct.
Would someone kindly explain how an object declared, in my example, as 'class A' can access methods from the derived class B?
In my experience, I've always declared the derived class as a pointer and then accessed methods from the base or derived class using the '->' construct. Oftentimes, I've stored the derived class as a pointer to the base and then performed a cast to convert when or if I needed access to the derived class's methods.
An insight is highly appreciated.
It cannot. The compiler is right to complain, there is no way this is valid. Remember that C++ is a static language, which means that the compiler will try to find a function named BFunc in A, which it cannot, as there is no such function.
This might be a compiler extension of some sort, but anyways, this isn't legal standard C++. Most probably, the author wanted to make BFunc a virtual method in A, which would have made the access legal.
Would someone kindly explain how an object declared, in my example, as 'class A' can access methods from the derived class B?
As explained, this cannot be.
I've always declared the derived class as a pointer and then accessed methods from the base or derived class using the '->' construct.
You can also do this with references, not just with pointers. Although this is done less often than pointers, so this might explain why you haven't encountered this yet.
Oftentimes, I've stored the derived class as a pointer to the base and then performed a cast to convert when or if I needed access to the derived class's methods.
Exactly, this is the correct way to access the derived class members. As then the compiler will know the type of the object and can actually find BFunc and call it. Now, if the type is not really a B, then you have undefined behavior, but yes, this is what one should do.
Also, please get your terminology right:
the class is instantiated as follows
If there are no templates involved, then there is no instantiation happening. The only thing you are doing here is declaring or more specifically defining a variable named tObject.
// The declaration of the reference as a reference to the base class is not a problem, and is actually performed in some STL implementations.
class A
{
};
class B : public A
{
public:
void f1() {}
};
int main()
{
A * a = new B; // You know its OK using pointers
A & a2 = *(new B); // Also OK, a2 is a reference for a place in memory which is-a-kind-of A
// a2.f1(); // Will not compile - compiler only knows for sure its of type A
((B&) a2).f1(); // This will work. There is really a B there
return 0;
}
I searched for this, but I feel I'm not finding the answer I'm after. So, simple version and hopefully someone can just say "here's how" and I'll be on my way :)
Essentially I want this:
class BaseObject
{
public:
BaseObject();
~BaseObject();
virtual bool FunctionX() =0;
virtual bool FunctionY() =0;
};
class ObjectA : BaseObject
{
public:
ObjectA();
~ObjectA();
bool FunctionX();
bool FunctionY();
bool FunctionZ();
};
.. same for ObjectB as above ..
...
vector<BaseObject*> myList;
ObjectA a;
ObjectB b;
myList.push_back((BaseObject*)&a);
myList.push_back((BaseObject*)&b);
myList.back()->FunctionX();
I know the code above is wrong, I'm just trying to get the overall concept over.
What I need:
A base class that defines functions that MUST be present in classes that inherit from it.
The ability to store the classes that inherit from it all in the same vector (cast as the base class).
The vector to know it can call the base classes defined functions.
The classes to be able to have their own, additional functions that the vector/base class do not need to be aware of.
I just noticed, you're deriving privately. BaseObject is a private base class of ObjectA. When you omit the inheritance specifier, you get private inheritance by default. Change the ObjectA declaration to
class ObjectA : public BaseObject...
Otherwise, code outside of the ObjectA scope is not allowed to know that ObjectA is-a BaseObject.
Your code is almost right. It misses the virtual for BaseObject's destructor, however, which will invoke undefined behaviour (e.g. crashes) in any typical usage scenario. This is the correct declaration:
virtual ~BaseObject();
Another thing you should consider is making your public functions non-virtual and your virtual functions private, with the public functions delegating to the private ones (called Non-Virtual Interface Idiom by Herb Sutter).
A few more things:
A base class that defines functions that MUST be present in classes
that inherit from it.
You won't be able to achieve this, at least in the literal sense, by any normal means. A class can derive from your abstract class but remain itself abstract by not defining your pure virtual functions.
The ability to store the classes that inherit from it all in the same
vector
Mind the difference between "class" and "object". A vector doesn't store classes but objects. In C++, classes cannot be used as objects (which is different in Java, for example). To "store classes" implies something like type lists in advanced template metaprogramming, a technique not related at all to your problem.
(cast as the base class).
You do not need to cast from subclass to base class.
I have a basic question that has bothered me for sometime.
When using a Class within a Class I can define the header of the Class I want to use in the header file. I have seen two ways of doing this and would like to know the difference between the two methods?
ex1
#include "ClassA.h"
class ClassB {
public:
ClassB();
~ClassB();
ClassA* a;
};
#endif
ex2 Here is the other way of doing it. The ClassA Header would be defined in ClassB source file.
class ClassA;
class ClassB {
public:
ClassB();
~ClassB();
ClassA* a;
};
#endif
What are the differences with these two methods?
The comlpete layout of the classA is known to the compiler when you include the class definition.
The second syntax is called Forward declaration and now classA is an Incomplete type for the compiler.
For an Incomplete type,
You can:
Declare a member to be a pointer or a reference to the incomplete type.
Declare functions or methods which accepts/return incomplete types.
Define functions or methods which accepts/return pointers/references to the incomplete type (but without using its members)
But You cannot:
Use it as a base class.
Use it to declare a member.
Define functions or methods using this type.
Use its methods or fields, in fact trying to dereference a variable with incomplete type.
So Forward Declaring the class might work faster, because the complier does not have to include the entire code in that header file but it restricts how you can use the type, since it becomes an Incomplete type.
The second method only allows you to create pointers to ClassA, as it's size is unknown. It may however compile faster as the header for the full definition for ClassA is not included.
The latter is a forward declaration. This way you can declare a pointer or reference to a class, even though you have not yet fully declared it. This can be used to resolve cyclic dependencies. What if, in your first example, A also wants to use a pointer to B. This wouldn't work, because when A is declared, B is not known yet. To solve this, you can use a forward declaration to tell the compiler that there is a class B, and you will tell it later what it looks like.
I have a class manipulating only shared_ptr to an inheritance hierarchy (quite simple, there are a few classes, say A, B, C etc. inheriting from a single class Base). Since I do not need to manipulate the instances of A, B, C... themselves, they are only forward declared. However, the compiler chokes when I try to pass a shared_ptr<A> to a method taking a shared_ptr<Base>, since the compiler does not know that A inherits from Base. Is there any other way than either static_pointer_castor #includethe header of class A? And if not, which one would you choose?
EDIT: adding some code
// in some file: (Base.h)
class Base
{
/*code*/
}
// in another file (A.h)
class A : public Base
{
}
// in my file (impl.cpp)
class A; // forward declaration
void Dummy()
{
std::shared_ptr<A> myPtr;
// we have somewhere: void sillyFunction(shared_ptr<Base> foo)
sillyFunction(myPtr); // does not compile, as no conversion is found.
}
Is there any other way than either static_pointer_castor #includethe header of class A?
No. In fact, the #include is the only way to do it properly (static_pointer_cast either wouldn't work or invokes undefined behavior). You can't cast ordinary pointers between incomplete subclass and superclass, either.
I have multiple classes that are quite different in their behavior, but at the same time, share common functions that have to access the member variables.
So what I want to do, is to create a templated member function to avoid extra copy-paste code duplication.
The final result should be like:
ClassA::CallFoo()
ClassB::CallFoo()
ClassC::CallFoo()
where CallFoo() is defined in a shared file like [weirdo hypothetical syntax]
<template this* T>::CallFoo(){T->memberX->DoStuff();}
Is something like that possible with C++? I cant seem to find anything concerning code reuse and multiple classes.
EDIT:
I have multiple classes, ClassA, ClassB, ClassC, ... ClassX, all of which have a member variable memberX. In order to use that member variable inside the member functions of the classes, I have to do some setup and preprocessing on that variable, which is equal for all of the classes. So ClassA can have a method DoCoolStuff1() which has to call [shared code] to get the updated shared variable, ClassB can have a method DoBoringStuff1() which also calls [shared code].
Unfortunately, memberX is not in my source code, but in library headers ClassA : public LibClass, so I cannot override it there.
If what you are saying is that all of these classes inherit from LibClass, which contains memberX, then just add one more layer of inheritance:
class myLibClass : public LibClass
{
void CallFoo() { // do stuff with memberX }
};
class classA : public myLibClass {};
class classB : public myLibClass {};
etc...