Is it necessary to instance the class another class has been derived from?
If I dont, I can access its methods anyway, like in this example:
#include <iostream>
struct Class1 {
public:
void func();
};
struct Class2 : public Class1 {
// Class1 c1; <-- is this necessary?
};
void Class1::func(){
std::cout << "function called" << std::endl;
}
int main() {
Class2 c2;
c2.func();
}
I get the expected function called.
But in some examples I see that the base class is being instanced in the derived class: Class1 c1;. What is it for?
Is it necessary to instance the class another class has been derived from?
No, it is absolutely not necessary.
But in some examples I see that the base class is being instanced in the derived class: Class1 c1;. What is it for?
Without knowing what those examples concretely deal with - i.e. what was the semantics of those classes - it's not easy to explain them in a meaningful way. However, when you create a data member of a certain type, your object has a sub-object of that type. So when you do:
struct Y { };
struct X
{
int a;
std::string b;
Y c;
};
Every object of type X will have a subobject a of type int, a subobject b of type b, and a subobject c of type Y. You would be accessing that with the dot notation, as done below:
Y foo();
X x;
std::cout << x.a;
x.b = "Hello, World!";
X.c = foo();
Similarly, when a class D derives from a base class B, it contains a sub-object of type B, and implicitly inherits all the data members of B:
struct B
{
int a;
std::string b;
};
struct D : B
{
bool c;
};
// ...
D d;
d.c = true;
d.b = "Hello, Base Class!";
d.a = 42;
Now in your case, the class Class2 apart from deriving from Class1 also has a data member of type Class1. Notice, that this data member is not the base sub-object of Class2, but an additional member sub-object. So what does this mean?
Take this with a grain of salt, but in order to develop intuition, you can think that inheritance models the "IS-A" relationship, while data membership models the "HAS-A" relationship.
So the fact that Class2 derives publicly from Class1 models the fact that "All Class2 objects are Class1 objects", and therefore inherit all of Class1's data members. This explains why objects of type Class2 have a base sub-object of type Class1.
On the other hand, the fact that Class2 has a data member of type Class1 models the fact that "All Class2 objects contain/embed/own an object of type Class1". This explains why objects of type Class2 have a member sub-object of type Class1.
Now in the particular case of the examples you mention both of the above semantics are modeled at the same time - i.e. a Class2 both IS-A and HAS-A Class1 - but that is by no means necessary. Not every thingy which IS-A widget also HAS-A widget.
I hope this makes sense to you in an abstract way. Whether the design is correct or not mostly depends on the semantics of your Class1 and Class2 objects, and on what they are meant to model, but the message is:
If Class2 derives from Class1, there is nothing that forces you to add a Class1 data member to Class2.
There is no need to have a base class member variable in the derived class in this case. Also polymorphism applies only for pointer and reference types.
No, it is not necessary.
class Base {
}
class Derived : public Base {
}
The Derived class will inherit the members of the Base class.
It definitely isn't necessary. Without seeing the examples you are referring to it's hard to tell why the author would have created the instance. Most likely it is to show what happens when Class2::func() calls c1.func().
Related
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;
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.
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.
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?
class base{
private:
int a;
public:
int b;
void setData(){
a = 10; b = 5;
}
};
class derived: public base{
private:
int c;
public:
// b is inherited
};
void main(){
derived D1;
D1.setData();
}
I learned that private members aren't inherited. So, the private variable a (in the base class) is not present in the derived class object. My question is when D1.setData() is called, how can it assign a value to a, if a doesn't exist?
I'm pretty sure I have this concept wrong, so can some one explain how this works? Are the base class members also created when the derived class object is created?
I learned that private members aren't inherited.
Of course they are inherited: otherwise, all member functions of the base class that need these private variables would be broken. Although private members are not accessible to the inheriting class, the base class retain full access to them.
Can some one explain how this works?
Layout of the inheriting class derived includes a place to store a, the private member of the base class. All methods of the base class can access base::a. At the same time, it remains inaccessible to the derived class: any attempt to access a from derived would cause a compile-time error.
Private member variables are inherited, but cannot be accessed externally. The memory pattern of inheritance is simple:
class base {
int x;
};
class subclassCpp : public base {
int y;
};
class subclassCStyle {
base a;
int y;
};
Now, subclassCpp and subclassCStyle have the exact same memory pattern, regardless of private/protected status, etc. This should illustrate how the memory is laid out.
For the other question, "Are the base class members also created when the derived class object is created?"
The answer is yes, a constructor is always invoked on the base class. If you don't add this yourself, the default constructor is automatically invoked. If the base class doesn't have a default constructor, it won't let you create a subclass constructor that doesn't properly invoke whatever constructor is necessary to initialize the base. So there is no legal way you can end up with a base class that hasn't been initialized when the subclass was created, as long as a constructor in the subclass was executed.