Call derived class' function from a base class' instance - c++

I'm a new user of programming c++. When I don't create a derived instance by new, it calls Base::test().
So what is the difference between Base b = d and Base* b1 = new Derived() ?
Base class
#include <iostream>
class Base
{
public:
virtual void test() { std::cout << "Base::test()" << std::endl; };
};
Derived class
#include "Base.h"
class Derived : public Base
{
public:
void test() { std::cout << "Derived::test()" << std::endl; };
}
main.cc
#include "Derived.h"
int main()
{
Derived d;
d.test();
Base b;
b = d;
b.test(); // why called Base::test() ?
Base* b1 = new Derived();
b1->test();
delete b1;
return 0;
}

Derived d;
d.test();
Base b;
b = d;
b.test(); // why called Base::test() ?
You created a Derived object d and Base object b. And later assigned b=d; Here object slicing is happening. After the assignment b has only Base part of the Derived class info in hand. So when you call b.test() it will call Base::test() instead Derived::test() function.
Base* b1 = new Derived();
b1->test();
delete b1;
Here you dynamically created a Derived class object in heap and returned the pointer of that object to Base class pointer. Here pointer is nothing but the memory address holding the Derived class object. And when you call b->test(), system internally identify the type of the object dynamically and it is returned as Derived. So it will call Derived::test() function.

Because that's not how polymorphism is implemented in C++.
This:
Base b;
b = d;
the second statement calls an assignment operator of b, i.e. b is still the same object b of class Base (except perhaps the data is now different, but the set of methods, i.e. the type is still Base).
You need to operate on pointers instead of references, because references cannot be changed and they are not changed.

You have mesh between two important concept in c++.
Run time polymorphism
Object Slicing
In c++ run time polymorphism is achieved using base class pointer with the help of virtual function. Since actual type of object is decided at run time. As we know base class pointer can store object of derived class. And then call to any function invoke call to derived class function(if base is virtual).
In you case you are assigning object of derived class to object of base class. This is Object slicing.

Related

Derived pointer to Base pointer conversion using static_cast, dynamic_cast,or explicit conversion won't call the base function

I have the following code.
#include <iostream>
using namespace std;
class Base
{
public:
virtual int f(){cout<<"Base"<<endl;}
};
class Derived:public Base
{
public:
int f(){cout<<"Derived"<<endl;}
};
int main()
{
Base b;
Derived d;
b.f(); ///base
((Base)d).f(); ///base
cout<<"----------------"<<endl;
Base *b1 = new Base;
Base *b2 = new Derived;
Derived *d1 = new Derived;
b1->f(); ///base
((Base*)d1)->f(); ///derived
((Base*)b2)->f(); ///derived
static_cast<Base*>(d1);
d1->f();///derived
static_cast<Base*>(b2);
b2->f();///derived
cout<<"----------------"<<endl;
Base *b5 = dynamic_cast<Base*>(b2);
Base *b6 = dynamic_cast<Base*>(d1);
if(b5)
b5->f(); ///derived
if(b6)
b6->f(); ///derived
return 0;
}
I want to ask why the derived *d1 OR b2 pointers when converted to a base using explicit cast (Base), static cast (static_cast(d1)) or dynamic cast (dynamic_cast(d1)) won't call the f() function of the base class after the conversion. It seems to call the f() function from the derived class every single time.
Also, strangely when I declare the objects this way. The conversion works and calls the base function.
Base b;
Derived d;
b.f(); ///base
((Base)d).f(); ///base
Now, I understood that the right way to access the f() from Base class would be d->Base::f(), but why should I use dynamic_cast or static_cast since they won't convert the derived pointer to base and call the right function. I would need a detailed explanation if possible. Thanks!
Fortunately, for both you and my keyboard, the explanation is trivial:
((Base)d) slices the object d to a value-copied Base instance.
((Base*)d1)->f() will still call the derived method since Base and therefore Derived are polymorphic types, and although ((Base*)d1) is a Base* pointer, it is pointing to a Derived object. Ditto for static_cast and dynamic_cast.
Reference: https://en.wikipedia.org/wiki/Object_slicing

why constructor of base class invokes first? [duplicate]

This question already has answers here:
Order of calling constructors/destructors in inheritance
(6 answers)
Closed 5 years ago.
While running the code below, why is the constructor of the base class is derived first even if we first declare an object of derive class.
#include<iostream>
using namespace std;
class base {
public:
base()
{ cout<<"Constructing base \n"; }
~base()
{ cout<<"Destructing base \n"; }
};
class derived: public base {
public:
derived()
{ cout<<"Constructing derived \n"; }
~derived()
{ cout<<"Destructing derived \n"; }
};
int main(void)
{
derived *d = new derived(); //d is defined ahead of the base class object
base *b = d;
delete b;
return 0;
}
Inheritance expresses an "is-a" relationship, so that all objects of class derived ARE objects of class base. derived objects have all of the data and methods that base objects do, plus the data and methods explicitly declared in the derived class declaration.
It's perfectly possible (and common) to write Derived classes that depend on the implementation of their Base classes. For example, suppose that we have
class Base {
public:
Base() { n = 5; }
int GetN() const { return n; }
private:
int n;
};
class Derived : public Base {
public:
Derived() { m = GetN() * 2; }
int GetM() const { return m; }
private:
int m;
};
Now we'd expect
Derived* d = new Derived();
std::cout << d->GetM() << std::endl;
to print 10, which is exactly what it should do (barring any mistakes on my part). This is a totally reasonable (if a little contrived) thing to do.
The only way the language can get code like this to work properly is to run the Base constructor before the Derived constructor when constructing an object of type Derived. This is because the Derived constructor depends on being able to call the GetN() method, which it inherits from Base, the proper functioning of which depends on the data member n having been properly initialised in the Base constructor.
To summarise, when constructing any Derived object, C++ must construct it as a Base object first because Derived is-a Base and will generally depend on it's implementation and data.
When you do
base* b = d;
in your code, you're declaring a variable b that is of type "pointer to a base object" and then initialising this variable with the same memory address held in d. The compiler doesn't mind you doing this because all derived objects ARE base objects, so it makes sense that you might want to treat d as a b. Nothing actually happens to the object here though, it's simply a declaration and instantiation of a pointer variable. The object pointed to by d already was a base object, since all derived objects are base objects.
Note that this explanation is intentionally a little fuzzy round the edges and is nowhere near a full explanation of the relationship between base and derived classes in C++. You'll want to go looking in other articles/books/the standard for that. I hope this is relatively easy to understand for beginners though.

Quickly assign all the members of a base object to a derived object in C++

Say we have one base class and one derived class:
class Base {
string s1;
string s2;
...
string s100; // Hundreds of members
};
class Derived : public Base{
string s101;
};
I want to assign a Base object base to a Derived object derived. I know we can't just use operator "=" to assign a base object to its derived object.
My question is: Do we have to make copies of all the members one by one? Like:
derived.s1 = base.s1;
derived.s2 = base.s2;
...
derived.s100 = base.s100;
Is there any faster or more concise way to do this? Overload an operator= with
the returned base object?
I want to assign a Base object base to a Derived object derived.
Provide an overload operator= for it:
class Derived : public Base {
Derived& operator=(const Base& b) {
Base::operator=(b); // call operator= of Base
s101 = something; // set sth to s101 if necessary
return *this;
}
};
Then you can
Base b;
// ...
Derived d;
// ...
d = b;
I know we can't just use operator "=" to assign a base object to its
derived object.
Of course you can (in the context of this question):
static_cast<Base &>(derived)=base;
Stock example:
class Base {};
class Derived : public Base {};
void foo()
{
Derived d;
Base b;
static_cast<Base &>(d)=b;
}
I know we can't just use operator "=" to assign a base object to its derived object
That's not true.
Do we have to make copies of all the members one by one? Like:
base.s1 = derived.s1;
base.s2 = derived.s2;
...
base.s100 = derived.s100;
Not really. As mentioned in the first comment by Danh.
base = derived
is enough, since it performs implicit dynamic upcast (i.e. converting from pointer-to-derived to pointer-to-base). See http://www.cplusplus.com/doc/tutorial/typecasting/

Does pointer to derived class create the Base class first or not?

I have the following code
#include <iostream>
using namespace std;
class B{
int i;
public:
B(){
cout << "Constructing B\n";
}
void print(){
cout << "Printing from B with size : "<<sizeof(*this)<<endl;
}
};
class D:public B{
int i;
public:
D(){
cout << "Constructing D\n";
}
void print(){
cout << "Printing from D with size : "<<sizeof(*this)<<endl;
}
};
int main(){
B b;
b.print();
D d;
d.print();
D* dp;
dp->print();
}
Which gives me following output:
Constructing B
Printing from B with size : 4
Constructing B
Constructing D
Printing from D with size : 8
Printing from D with size : 8
So is it true that while you create a pointer to derived class it doesn't create the instance of a base class first? I don't think its true though because the size of D class is the proof. But its not even calling the base class constructor. Can anyone explain this?
Pointers do not create anything. Pointers are just pointers - scalar objects that contain addresses. It is your responsibility to make your pointers to point to proper locations in memory.
In your example pointer dp is not initialized. You never made it to point anywhere, so it points nowhere. Your attempt to call dp->print() produces undefined behavior. End of story.
Right now your pointer isn't be initialized at all, so trying to use it gives undefined behavior. Try something like:
D *dp = new D;
dp->print();
delete dp;
Or to do it better, something like:
std::unique_ptr<D> dp = std::make_unique<D>();
dp->print();
...and the unique_ptr will automatically delete the D when it goes out of scope.
Note, however, that you've define print as a non-virtual function, so the function that's invoked will depend on the type of pointer (or reference) used, not the type of the object it refers to. In addition, you haven't defined a virtual dtor.
Therefore, if you were to do something like:
B *p = std::make_unique<D>();
p->print(); // would invoke B::print, even though the object is a D
...and when it went out of scope, it would be destroyed incorrectly so you'd get undefined behavior. To correct this, you want to change B to something like this:
class B{
int i;
public:
B(){
cout << "Constructing B\n";
}
virtual void print(){
cout << "Printing from B with size : "<<sizeof(*this)<<endl;
}
virtual ~B() = default;
};
When you do this, the answer is "yes"--when you create the derived object, it'll first invoke the ctor for the base class, then the ctor for the derived class. When the derived object is destroyed, that is reversed: first the dtor for the derived class will be invoked, then when it finishes the dtor for the base class will execute.
It is constructing the base class before the derived class. Your output reflects this. Look at this
//Constructs Base class
Constructing B
//Constructs Derived class
Constructing D
//Prints from derived
Printing from D with size : 8
The reason that your code prints Printing from D with size : 8 twice without calling the constructor is that your code never creates a second instance of D.
D* d;
^^^^ Declares a pointer to a D, Does not create a D!
When you call d->print(); it is undefined behavior as d does not point to an instance of D. Finally, your code prints a value determined at compile time (sizeof(D) is a compile time value) and does not touch the this pointer your code runs.
See the documentation for sizeof here.
You can assign a pointer of Base with a Derived object by using the powerful polymorphism. That is possible because Derived implements everything that Base contains. Thus, it is implicit that Derived underlying instantiates the Base during its own instantiation.
class Base
{
public:
Base()
{}
}
class Derived : public Base
{
public:
Derived()
{}
}
Derived *derived = new Derived();
Base *base = derived;

How can i get a derived class data member via base class pointer (upcasting)

class Base{
common methods
};
class Derived: public Base{
private:
int a;
char* arr;
public:
Ctor
Dtor
};
int main(){
Base* B;
Derived D;
B = &D;
how can i extract information from B about D's data members?
don't mind the syntax error, I'm more concerned about how to get the data members or how to comper two derived classes if I have more then one derived class.
When you know that the pointee is a Derived, then you can downcast the pointer from Base* to Derived*, preferably by using a static_cast. When you don't know, but the base class has one or more virtual methods, then you can check via dynamic_cast. But preferably you should have virtual methods in Base so that you can do whatever it is without casting, or else, you should ideally not be throwing away the specific type information in the first place.
you will first need to cast it to the derived type:
assume v2 is a string member of the Derived class
if (auto* d = dynamic_cast<Derived*>(B))
std::cout << "v2: " << d->v2 << std::endl;
Define virtual function in Base then implement it in Derive class. Does it help?