C++ - Dynamic Binding and Object Instances Not Accessing Derived Methods - c++

I haven't written anything in C++ in quite some time, and am running into some inheritance issues that are confusing.
First question - From my understanding, a base class with a virtual method whose derived class implements that method should call the derived method IF the method is called from a pointer to the base class. Why does it need to be a pointer? Is this because of the way vtables are implemented? If so, why is an implementation detail not abstracted in the actual specification? I am trying to understand why this is the case. Is there a time when you want the base class to be called, only if the object is not a pointer? I thought the point was for pointers to objects to behave similarly to those objects.
Second question - In the below code, I ran a test to see that derived class methods were called if the method of access was a pointer. Then, I went back and tried to use the same method to turn the instance into a pointer to achieve the same binding. However, there is no cast that will allow me to use the class as a derived class if it was, at any point, stored as an object instance. Why is this? If, for example, I took the same objects (further below) and put them in a vector then it works correctly.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class BaseClass {
public:
virtual void A();
virtual void B();
};
void BaseClass::A() {
cout << "In base A" << endl;
}
void BaseClass::B() {
cout << "In base B" << endl;
}
class DerivedClass1 : public BaseClass {
public:
void A();
void B();
};
void DerivedClass1::A() {
cout << "In Derived A" << endl;
}
void DerivedClass1::B() {
cout << "In Derived B" << endl;
}
int main(int argc, char** argv) {
string cmd;
BaseClass bc;
DerivedClass1 dc1;
vector<BaseClass> list;
list.push_back(bc);
list.push_back(dc1);
cout << "Calling by " << endl;
for(int i = 0; i < list.size(); i++) {
// There is no possible cast to BaseClass* that causes A or B to call the derived class
(dynamic_cast<BaseClass*>(&list[i]))->A();
(dynamic_cast<BaseClass*>(&list[i]))->B();
}
// However, the below code, although it stores the same addresses, etc. works fine.
vector<BaseClass*> list_ptrs;
list_ptrs.push_back(&bc);
list_ptrs.push_back(&dc1);
cout << "Outputting Pointers" << endl;
for(int i = 0; i < list_ptrs.size(); i++) {
list_ptrs[i]->A();
list_ptrs[i]->B();
}
getline(cin, cmd);
}
Sorry if I am just misunderstanding something very basic, but it seems to be an inconsistency in the way that dynamic binding works, and I can't find a decent explanation (all Google returns are people trying to access base class methods...).
Any assistance would be appreciated,
Thanks,
-Alex

This is wrong:
BaseClass bc;
DerivedClass1 dc1;
vector<BaseClass> list;
list.push_back(bc);
list.push_back(dc1);
Your vector can only store BaseClass objects. Trying to stuff a DerivedClass into something that can only hold BaseClass objects is termed as object slicing, which you do not want happen. Object slicing means just that -- you are "slicing off" the DerivedClass's attributes so that it is a BaseClass.
Either have a vector of BaseClass pointers, or two separate vectors, one of BaseClass objects, the other of DerivedClass objects.
vector<BaseClass*> theList;
theList.push_back(&bc);
theList.push_back(&dc1);
You should now see the virtual functions work as expected.

Related

Question regarding polymorphiic functions in C++

I am new to C++ and currently I am studying polymorphism.
I have this code:
#include <iostream>
class Base
{
public:
void say_hello()
{
std::cout << "I am the base object" << std::endl;
}
};
class Derived: public Base
{
public:
void say_hello()
{
std::cout << "I am the Derived object" << std::endl;
}
};
void greetings(Base& obj)
{
std::cout << "Hi there"<< std::endl;
obj.say_hello();
}
int main(int argCount, char *args[])
{
Base b;
b.say_hello();
Derived d;
d.say_hello();
greetings(b);
greetings(d);
return 0;
}
Where the output is:
I am the base object
I am the Derived object
Hi there
I am the base object
Hi there
I am the base object
This is not recognizing the polymorphic nature in the greetings functions.
If I put the virtual keyword in the say_hello() function, this appears to work as expected and outputs:
I am the base object
I am the Derived object
Hi there
I am the base object
Hi there
I am the Derived object
So my question is:
The polymorphic effect is retrieved when using a pointer/reference?
When I see tutorials they will present something like:
Base* ptr = new Derived();
greetings(*ptr);
And I was wondering if had to always resort to pointers when using polymorphism.
Sorry if this question is too basic.
For polymorphic behavior you need 2 things:
a virtual method overridden in a derived class
an access to a derived object via a base class pointer or reference.
Base* ptr = new Derived();
Those are bad tutorials. Never use owning raw pointers and explicit new/delete. Use smart pointers instead.
Just add a virtual declaration to the method to allow it to be overridden when using references to the base class:
virtual void say_hello() {...}
in both classes (or at least just the base class).

How to store a pointer to SubClass object in a BaseClass pointer array?

I am trying to create a BaseClass array that stores SubClass objects. Below are the follow steps I use to do this:
I create a BaseClass array.
I create a new SubClass object to be stored in the array.
I call the printSelf() function of that object in the array.
The method incorrectly calls the BaseClass function, not the SubClass function.
The error here is that the object stored in the BaseClass array is of a BaseClass object. I need it so that the BaseClass array stores an object of type SubClass.
The problem is designed such that if there were to be multiple SubClasses (i.e. SubClassA, SubClassB, SubClassC...) they would all be stored in a single array.
I've tried various other solutions on StackOverFlow. None so far have provided a solution as to why creating a SubClass object will not store its class type properly in a BaseClass array.
class BaseClass {
public: void printSelf() { cout << "This element is a BaseClass." << endl; };
};
class SubClass : public BaseClass {
public: void printSelf() { cout << "This element is a SubClass." << endl; };
};
class House {
public: House();
private: BaseClass* subClassArray[1];
};
House::House() {
subClassArray[0] = new SubClass;
subClassArray[0]->printSelf();
}
int main() {
House houseMain;
}
I expect the output to be "This element is a SubClass."
Instead, the output I am receiving is "This element is a BaseClass."
You need to declare printSelf as virtual. In addition you almost certainly want to add a virtual destructor to your class.
class BaseClass {
public: virtual void printSelf() const { cout << "This element is a BaseClass." << endl; };
////// <- must ///// <- recommended
virtual ~BaseClass() = default; // <-- HIGHLY recommended
};
class SubClass : public BaseClass {
public: void printSelf() const override { cout << "This element is a SubClass." << endl; };
//////// <- recommended
};
The following line is twice problematic.
private: BaseClass* subClassArray[1];
First, it is using raw C-style pointers. Second, it uses a raw C-style array. Both are not recommended in today's C++ development. You want to read about smart pointers, std::vector and std::array.
Do NOT use any casts here, this is a non-option.
The issue is that you are hiding the printSelf method, rather than overriding it. Hence, the base class' version of printSelf is used when you have a pointer to the base class type.
There are two options to get around this, either you cast subClassArray[0] to the subclass type (not recommended unless you don't own the base class) or you mark printSelf as virtual and override it in the subclass.

Is it possible to creat a derived object from a base object through downcast?

Base class
class Base
{
public:
Base()=default;
virtual void f(){cout << "base class\n";}
virtual ~Base(){}
};
Derived class
class Derive : public Base
{
public:
Derive()=default;
void f() override {cout << "derived class\n";}
};
main function
int main()
{
Base* bsd = new Base;
Derive* dru = new Derive;
if(Derive* drd=dynamic_cast<Derive*>(bsd)){
drd->f();
cout << "downcast successful\n";
}else{
cout << "downcast failed\n";
}
if(Base* bsu=dynamic_cast<Base*>(dru)){
bsu->f();
cout << "upcast successful\n";
}else{
cout << "upcast failed\n";
}
delete bsd;
delete dru;
}
It turns out upcast works fine, while downcast failed. It seems makes sense that way. If the derived class contain member objects that are not declared in the base class and do not have default constructors, what gonna happen during downcast?
Besides, the target pointer *drd(*bsd) created through dynamic_cast points to the same object with the pointer *bsu(*dru) to be cast. So delete once will be enough. We will not have a dangling pointer, right?
Casting does not create anything new or changes objects in any way. Casting changes the interpretation of an existing object, so if an object is not a Derive, there is no way to make it a Derive through casting.
Note that Derive is also a Base, because inheriting creates an "is a" relationship. That's why upcasting works: all it does is telling the compiler that it should treat the pointed to object as Base, even though the object is actually Derive.
It makes no difference in your program, so here is an illustration of what the cast does:
class Derive : public Base
{
public:
Derive()=default;
void f() override {cout << "derived class\n";}
void added() {cout << "hello" << endl; }
};
dru->added(); // Works
Base* bsu=dynamic_cast<Base*>(dru);
bsu->added(); // Does not compile
Essentially, the cast "hides" added interfaces from the compiler, ordering it to treat a Derive object as if it were Base. Of course, the overrides continue to be called correctly, because the overriden member-functions are part of the Base's interface.
I'm not sure I got your question right, but yes, you can safely delete a derived class using a base pointer, if the destructor is virtual.
A "dangling pointer" is something different: After you have deleted bsd and dru, you can not use these pointers anymore, they have become dangling pointers, because they point to deleted memory that you don't own anymore.
dynamic_cast checks run-time type check and provides a safe conversion. If a meaningful conversion is possible then you'd get a valid object after downcast. As you pointed out, in your example the underlying object was of "base class". Run time type check failed. However if the underlying object was of "derieved class" dynamic_cast would have succeeded. ex:
class CBase
{
public:
CBase(void);
virtual ~CBase(void);
virtual void identify()
{
std::cout << "base class" << std::endl;
}
};
class CDerieved : public CBase
{
public:
CDerieved(void);
virtual ~CDerieved(void);
virtual void identify()
{
std::cout << "Derieved class" << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CDerieved* pderieved = new CDerieved;
pderieved->identify();
CBase* pb = static_cast<CBase*>(pderieved);
pb->identify();
CDerieved* pd1 = dynamic_cast<CDerieved*>(pb);
pd1->identify();
return 0;
}
The above code will succeed.
But please remember, if you find needing a downcast, then the design needs to be revised.

C++ polymorphism and slicing

The following code, prints out
Derived
Base
Base
But I need every Derived object put into User::items, call its own print function, but not the base class one. Can I achieve that without using pointers? If it is not possible, how should I write the function that deletes User::items one by one and frees memory, so that there should not be any memory leaks?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Base{
public:
virtual void print(){ cout << "Base" << endl;}
};
class Derived: public Base{
public:
void print(){ cout << "Derived" << endl;}
};
class User{
public:
vector<Base> items;
void add_item( Base& item ){
item.print();
items.push_back( item );
items.back().print();
}
};
void fill_items( User& u ){
Derived d;
u.add_item( d );
}
int main(){
User u;
fill_items( u );
u.items[0].print();
}
You need to use pointers, and you need to give your base class a virtual destructor. The destructor does not have to do anything, but it must exist. Your add function then looks like:
void add_item( Base * item ){
item->print();
items.push_back( item );
}
where items is a vector<Base *>. To destroy the items (assuming a virtual destructor):
for( int i = 0; i < items.size(); i++ ) {
delete items[i];
}
items.clear();
You need a virtual destructor for base to make sure objects of type Derived get destroyed properly when calling delete on a pointer of type Base.
class Base{
public:
virtual void print(){ cout << "Base" << endl;}
virtual ~Base( ) { } // virtual destructor
};
Then you can use Boosts ptr_vector to store pointers to your objects that get deleted when the container gets destroyed.
just explaining:
In order to understand what is going on, you may try to define class Base abstract (e.g. defining any method pure virtual). In this case I expect you'll see compiler errors.
This way you'll recognize what vector actually does: it creates new instances of class Base by means of copy construction when you push_back( derived ).
This is why you want to use pointers instead. Then vector works with your originally created objects of type Derived instead of own copies of type Base.

Why and Where do we use down casting?

Are there any cases where we do down casting of objects?
If we do, why?
I have observed a way of hiding implementation using the below code. Is this the correct way to do? Is there any better way to achieve the same.
class A{
public:
A();
virtual ~A();
//exposed virtual functions
};
class AImpl : public A{
public:
AImpl(A *obj);
virtual ~AImpl();
//exposed virtual functions++
};
class Helper{ //utility class so i am making constructor and assignment operator as private
public:
static bool doWork(A *obj){
AImpl *objImpl = dynamic_cast<AImpl *> (obj);
return doWork(objImpl); // some internal function
}
private:
Helper();
Helper(const Helper& obj);
const Helper& operator=(const Helper& obj);
};
The question still does not makes sense. I agree. I still have not figured out a proper way of hiding the implementation details from the client.
UncleBens
I termed this thing wrongly as Object slicing. Basically, I was referring to this (Object Slicing) as the information related to derived part is missing.
S.Soni
Thanks for giving a wonderful explaination. Now, I can really put forward question.
Consider a clients perspective. The only class which are visible to him is class A and the Helper class (because I have hidden implementation behind AImpl
Client has to write the following code as he is unaware of AImpl class
int main(){
A *a = new A();
Helper.doWork(a);
// ...
}
As you said AImpl * in this case will actually be pointing to the base class object, which is wrong (you have explained it with a great example), so this approach of hiding implementation is not correct.
Any attempt to access a derived class member function will result in a crash (and correctly so).
How should I go about hiding the implementation in this case? This is a design problem now?
**Are there any cases where we do down casting of objects**
The purpose of dynamic_cast is to perform casts on polymorphic types. For
example, given two polymorphic classes Band D, with D derived from B, a
dynamic_cast can always cast a D* pointer into a B* pointer. This is because a base
pointer can always point to a derived object. But a dynamic_cast can cast a B* pointer
into a D* pointer only if the object being pointed to actually is a D object.
**`Is there any better way to achieve the same`**
Perhaps the most important of the new casting operators is dynamic_cast. The
dynamic_cast performs a run-time cast that verifies the validity of a cast.
1) Your class is not polymorphic.A class that declares or inherits a virtual function is called a polymorphic class
2) Syntax of dynamic_cast is dynamic__cast (expr)
1st Edit :
Try like this , it will work
class A
{
public:
A();
virtual ~A();// Notice here i have put virtual
};
class AImpl : public A
{
public:
AImpl(A *obj);
~AImpl();
};
class Helper
{
public:
Helper(){}
static bool doWork(A *obj)
{
AImpl *objImpl = dynamic_cast<AImpl*> (obj);
return true;
}
};
Study this example :
class Base
{
public:
virtual void f() { cout << "Inside Base\n"; }
// ...
};
class Derived: public Base
{
public:
void f() { cout << "Inside Derived\n"; }
};
int main()
{
Base *bp, b_ob;
Derived *dp, d_ob;
dp = dynamic_cast<Derived *> (&d_ob);
if(dp) {
cout << "Cast from Derived * to Derived * OK.\n";
dp->f();
} else
cout << "Error\n";
cout << endl;
bp = dynamic_cast<Base *> (&d_ob);
if(bp) {
cout << "Cast from Derived * to Base * OK.\n";
bp->f();
} else
cout << "Error\n";
cout << endl;
bp = dynamic_cast<Base *> (&b_ob);
if(bp) {
cout << "Cast from Base * to Base * OK.\n";
bp->f();
} else
cout << "Error\n";
cout << endl;
dp = dynamic_cast<Derived *> (&b_ob);
if(dp)
cout << "Error\n";
else
cout << "Cast from Base * to Derived * not OK.\n";
cout << endl;
bp = &d_ob; // bp points to Derived object
dp = dynamic_cast<Derived *> (bp);
if(dp) {
cout << "Casting bp to a Derived * OK\n" <<
"because bp is really pointing\n" <<
"to a Derived object.\n";
dp->f();
} else
cout << "Error\n";
cout << endl;
bp = &b_ob; // bp points to Base object
dp = dynamic_cast<Derived *> (bp);
if(dp)
cout << "Error";
else {
cout << "Now casting bp to a Derived *\n" <<
"is not OK because bp is really \n" <<
"pointing to a Base object.\n";
}
cout << endl;
dp = &d_ob; // dp points to Derived object
bp = dynamic_cast<Base *> (dp);
if(bp) {
cout << "Casting dp to a Base * is OK.\n";
bp->f();
} else
cout << "Error\n";
return 0;
}
From your code and the information that the passed in pointer actually points to an A, and not an AImpl, also the constructor AImpl that accepts an A*, I gather that what you want it:
class Helper{
public:
static bool doWork(A *obj){
AImpl objImpl(obj); //construct an AImpl instance, using available constructor
return doWork(&objImpl); // some internal function
}
};
There is no way to cast a base instance into an instance of a derived class (where would the missing derived part come from??).
Well, if the following holds true (not the only valid reasons, but a common one):
you have a MVC like architecture
you want to hide the implementation details from client code (no-na...)
you need to pass some references from core to client-code (handles of all sorts, etc.)
the only valid implementation of the public interfaces must be in the core of the MVC part
then using this way is quite common.
However, if it is simply not allowed to use any other implementation (because only your library core may implement the interface), then asserting the type would be nice too; this would provide a nice landing in the debugger or crash-dump for any user of the library who messed with it in a way it should not be done. Of course, the documentation should clearly indicate that deriving from A is a bad idea.
Your example code contains at least 4 syntax errors, so it's hard to judge what you're trying to do.
And it logically won't work either. You have a class AImpl that inherits A, then a member function that takes an A and appears to try to dynamic-cast it to an AImpl. But it isn't an AImpl, because it's just an A, as that is how the parameter is declared. If you were to pass an instance of AImpl to that function, it would be sliced down to just an A.
You could make it a reference or pointer to an A, and then it could be an AImpl. Dynamic casts are only ever of use on references or pointers.
Down-casting is used when we have a variable or parameter that has the static type of a base class but we logically know that it is (or might be) of a derived class. It is avoided wherever possible because it means that the compilation process is not able to completely check the type-correctness of the program, i.e. the answer to the question "are you trying to put a square peg into a round hole" cannot be fully answered until runtime.
Update after question was edited
It sounds like you want clients of your library to have access to a limited interface to an object, A, but when they pass it to a function in your library you will have access to the full interface. You could just use friend for this.
class A
{
friend class LibraryThing;
void visibleToLibraryThing();
public:
// ctor, etc.
void visibleToAll();
};
class LibraryThing
{
public:
void foo(A &a)
{
a.visibleToLibraryThing();
}
};
The LibraryThing class can access the private members of A, because it is declared as a friend of A.
The downside is that LibraryThing can access everything in A, so it means that as the author of the library, you won't be able to benefit from encapsulation. Only users of your library will.
You can use PIMPL to hide implementation details, mask dependencies, and speed up builds.
http://www.gotw.ca/gotw/028.htm
http://www.ddj.com/cpp/205918714
http://www.gotw.ca/gotw/024.htm