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.
Related
This question already has answers here:
Downcasting using the 'static_cast' in C++
(3 answers)
Closed 3 years ago.
I have the below piece of code where I have a base class and a derived class. Both base class and derived class are having a function member sharing the same name. In the main(), I have typecasted a base class object to a derived class pointer and trying to call the function. To my utter surprise, it is calling the derived class function member. As far as I know, the base class object won't be having any information about the derived class object. So, how come my derived class pointer is still able to access the derived member function?
In the case of upcasting, I do understand derived class object will be having the contents of the base class that's why a base class pointer pointing to a derived class object will work as expected.
Can someone please help me in understanding how the derived class member function is getting called in this even when I am having a derived class pointer pointing to a base class object(which is having no information of derived class)?
#include<iostream>
using namespace std;
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
public:
void b()
{
cout << "derived";
}
};
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
d1->b();
return 0;
}
In your specific case, it's perfectly normal that b is called.
You have a pointer to Derived class, b it's not virtual. So the compiler will generate a call to Derived::b method.
Now, when b will be executed, as you put crap in the this pointer, it's undefined behavior.
But in your case, as you do not access the this pointer, there's no probleme.
Cast a base class to derived class results undefined behavior
As I know, the function doesn't takes any extra space in memory, it stores like the normal function. You can see a member function as a normal function with an extra this pointer. In general, which function to call is determined by the type of the object pointer. But the virtual function is different, it is called by virtual function table, in your code, there is no virtual function declared. So there is no virtual function table.
You can see your code in a different way:
void derived_b(derived* this)
{
cout << "derived";
}
void base_b(base* this)
{
cout << "base";
}
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
derived_b(d1);
return 0;
}
If you define some member in class, and use it in function b, it may cause some error.like
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
int a;
public:
derived(){a = 1;}
void b()
{
cout << "derived" << a;
}
};
your code in main() may cause error because the object b don't have any member in memory.
A derived class object can be assigned to a base class object in C++.
Derived d;
Base b = d; // It's Ok
But why can't a base class object be assigned to a derived class object?
Base b;
Derived d = b; //Not Ok. Compiler give an error
Edit:
Sorry, but this question was actually asked durring an interview.
Inheritance is an "is-a" relationship, but it's one-way only.
If you have e.g.
struct Base { /* ... */ };
struct Derived : Base { /* ... */ };
Then Derived is a Base, but Base is not a Derived.
That's why you can assign or initialize a base-class instance with a derived object (but beware of object slicing), but not the other way around.
A derived object is a base object, with additional information.
You can initialize a complete base object from the base part of a derived object, no problem.
But if you want to construct a derived object from just a base object, what should the additional information be initialized with?
If you want to provide defaults for that additional information, you can do so by declaring a Derived(Base const &) constructor. But since it does not work in the general case, it isn't done for you.
In general a C++ compiler will disallow the assignment of a object of a base class to a derived one as, in a sense, the derived class is a superset of the base class: i.e. it wouldn't know how to to deal with any members that are specific to the derived class.
That said, you can handcode such a possibility by an appropriate overload of the assignment operator and an appropriate constructor in the derived class.
Aside from perhaps overcomplicating the language, I don't see why a trivially copyable base class instance could not be assigned to a derived class that contains no additional members. But this is not implemented in any C++ standard at the time of my writing. Furthermore, to my mind at least, the consequence of having any uninitialised derived class members and bypassed derived class constructors doesn't require materially more consideration on the part of a programmer than the perils of object slicing if a derived class instance is assigned to a base class! In other words, I don't think the hackneyed retort "because it makes no sense" makes much sense in itself.
Reference: http://en.cppreference.com/w/cpp/types/is_trivially_copyable
If there is a public inheritance b/w Base and Derived class , then that is ‘is a’ relationship .
And in “is a” Relationship Derived is a Base .
One of the most importance point here is that “is a Relation ” is not bi-directional.
I.e. Derived is a Base But Base is not Derived.
Let say we have two classes Shape and Circle.
Shape is a Base and Circle is publically Inherited from Shape.
so, Circle is a Shape But Shape is not Circle
//main.cpp
#include <iostream>
#include <string>
using namespace std;
class Shape
{
private:
int x;
public:
Shape(int i):x{i}
{
cout << "Base constructor called " << endl;
}
};
class Circle : public Shape
{
private :
string color;
public :
Circle(int radius) : Shape{ radius }
{
cout << "Derived constructor called " << endl;
}
Circle(int radius, string color) : Shape{ radius }, color{ color }
{
cout << "Derived constructor called " << endl;
}
};
int main()
{
//This is valid . since a circle is a shape
Circle s(1);
Shape a = s;
return 0;
}
But you can't do this since a Shape is not a circle
And inheritance is not Bi Directional here
Shape s(1);
Circle a = s;
If you do this you will get a compiler error
no suitable user-defined conversion
from "Shape" to "Circle" exists
How about using a temporary reference?
Base b;
Derived d;
Base & d_ref = d;
d_ref = b;
Lets say I have a base class with protected member:
class Base
{
public:
Base(int data)
: m_attribute(data) {}
protected:
int m_attribute;
};
and derived class from base:
class Derived : public Base
{
public:
int get_attribute()
{
return m_attribute;
}
};
First of all: I can do this, right? Is this totally legal?
If yes, then here is the question:
I can't change anything in a Base class;
I have a Base class object, and I need to access its m_attribute member;
Should I do downcasting from this base class object to derived class object first, and then call get_attribute() function? Something like this:
Base base(5);
Derived* derived = static_cast < Derived*>(&base);
int base_attribute = derived->get_attribute();
Or what are other ways to access protected member? I know that friend function is an option, but I can't change anything in the base class
Should I do downcasting from this base class object to derived class object first, and then call get_attribute() function?
Most definitely not. An instance of a base class is not an instance of a derived class. Your conversion is ill-formed.
Here is a valid way:
struct kludge : Base {
kludge(const Base& b): Base(b) {}
operator int() {
return m_attribute;
}
};
usage:
Base base(5);
int foo = kludge(base);
This kludge works by copy constructing the base sub object of the derived type. This of course depends on the base being copyable - which your Base is. It's easy to tweak to work with movable as well.
As a syntactic sugar, the kludge is implicitly convertible to the type of the member. If you prefer, you could use a getter.
if base class doesn't have a default constructor after overloading it to take some arguments and no default one is there then the derived classes must use member-initializer list to initialize the base part otherwise you cannot instantiate the derived class getting the compiler complaining about missing default constructor in base class:
class Base
{
public:
// Base(){} default constructor by default the compiler creates one for you unless you overload it so the next one taking one parameter will hide this one
Base(int data) // hides the default ctor so derived classes must use member-initializer list
: m_attribute(data) {}
protected:
int m_attribute;
};
class Derived : public Base
{
public:
Derived() : Base(0){} // you must use member intializer list to initialize the part Base
//Derived(int x) : Base(x){} // also ok
int get_attribute(){ return m_attribute; }
};
int main()
{
Derived dervObj;
Derived* derived = static_cast < Derived*>(&baseObj);
int base_attribute = derived->get_attribute();
cout << base_attribute << endl;
}
also you cannot cast the address of class base to derived object but cast an object of base class to derived one.
so in your example writing in main:
Derived* derived = static_cast < Derived*>(&baseObj); // is like writing:
char* cp = static_cast < char*>(&int); // you must convert a variable not a type
why you want to access protected members from outside??? keep in mind that public inheritance will copy all the members of base to derived class but private.
using friendship or making member data public will make it possible to access it from outside but it undermines the principles of data-hiding and encapsulation however friendship in some cases it's a must and there's no other alternative then use it carefully but making data public it's better to get back to structs
The Derived class can access and modify the public and protected Base class properties and methods.
Then, you can't case Base into Derived.
Derived inherit from Base, so Derived is a Base.
But a Base is not a Derived (a Car is a Vehicle, a Vehicle is not a Car).
So if you need a getter, put it directly into Base, or instanciate a Derived instead of a Base.
Firstly:
Derived* derived = static_cast < Base*>(base);
This is not valid and illegal. Won't compile. You can't static cast Base to Base*.
And to answer your question:
Base base(5);
Derived& derived = static_cast<Derived&>(base);
std::cout << derived.get_attribute();
Or if you want to use a pointer because you think you're cooler:
Base base(5);
Derived* derived = static_cast<Derived*>(&base);
std::cout << derived->get_attribute();
EDIT: static_cast doesn't have any overhead on runtime. It is static, hence it's a compile-time thing. Both methods will yield the same result.
Is it an O.K. design if i return an instance of Derived class from Base class member function(created using new Derived()) ?
Also this involves the need to forward declare the Derived class and also make the Derived class constructor public.
Code Sample :-
Class Base
{
public:
Base() {}
Derived* get_new_derived(int X)
{
Derived *der = new Derived(X);
return der;
}
}
Class Derived : public Base
{
private:
int _X;
protected:
Derived(int X) { _X = X; }
public:
Derived* get_new_derived(int X)
{
Derived *der = new Derived(X);
return der;
}
}
I have one more derived class(say Derived1). Now let's say :-
Usage1 :
Derived1* der1 = new Derived1();
Derived * der = der1->get_new_derived(10);
Usage2 :
Derived1* der1 = new Derived1();
Base* bs = der1;
Derived * der = bs->get_new_derived(10);
In the general case, this usually indicates bad design - a base class shouldn't normally know/care about its derived classes.
Note that you can return a pointer to Derived typed as Base* - that's the principle of the Factory Method design pattern. Perhaps this fits your actual scenario?
Note however that all rules have exceptions. If your (base class + derived classes) represent a tighly coupled and coherent unit (such as a Tree interface with two subclasses FastTree and SmallTree, optimised for different purposes), it is acceptable for them to be aware of each other, and Tree defining such functions as:
std::unique_ptr<SmallTree> Tree::createSmallCopy() const
{
return { new SmallTree(/*args*/) };
}
std::unique_ptr<FastTree> Tree::createFastCopy() const
{
return { new FastTree(/*args*/) };
}
So it depends on your actual use case. I'd generally be wary of such design, it but it has its uses.
As a side note, in modern C++, you should never use an owning raw pointer - use a smart pointer like std::unique_ptr or boost::shared_ptr.
How about this?
// The Curiously Recurring Template Pattern (CRTP)
template<class Derived>
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
// ...
};
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Yes you can do it. The question is whether you should.
You shouldn't do it since it implies Base knows Derived which isn't proper object oriented design. The dependencies should be one way - derived knows the Base and not vice versa.
So private members in the base class are also in the inherited class but not accessible in it, right?
Are they actually in the memory allocated to the the inherited object?
Are they actually in the memory allocated to the the inherited object?
Yes, they need to exist. The private members are part of the implementation detail of the base class. Without them, in general, the base class wouldn't be able to function (which is why they exist in the first place).
Making them private just allows the base class to create its implementation however it chooses, without exposing that to anybody, including the subclass.
Yes. Just for example, you can use a public function from the base class that manipulates private data, even in an instance of the derived class:
class Base {
int x;
public:
Base() : x(0) {}
void inc() { ++x; }
void show() { std::cout << x << "\n"; }
};
class Derived : public Base {
};
int main() {
Derived d;
d.show();
d.inc();
d.show();
}
With a properly functioning compiler, this must display:
0
1
...showing that the data in the Base object is present in the Derived object, even though it's not (directly) accessible.
Of course with almost anything in C++, there's the "as-if" rule -- if the compiler can determine that it can somehow produce the correct observable behavior for the program, even without including the private part(s) of the base class, then it's free to do so. The most obvious example of this would be if you included something (member function or data) in the base class that was simply never used in practice.
Yes they are,
When object of the derived class is being constructed all of its base classes are first being constructed as well.
Consider this example:
class Base
{
int x;
public:
Base(int px)
: x(px)
{
}
};
class Derived : public Base
{
int y;
public:
Derived(int px, int py)
: y(py), Base(px)
{
}
};
This example compiles and works and Base is initialized (constructor is called) before you reach the body of the Derived constructor.