In this inheritance program I create 2 classes which A is parent and B is child class . and i crate cons of both classes and also use
Destructor, and both classes have tow objects . # MY question is that
when my program is run then its output show 2 Destructor of class a
why ?
#include <iostream>
using namespace std;
class A
{
int a;
public:
A(int a1) // cons(A)
{
a = a1;
}
A() {} // Dis(A)
~A() { cout << "A Disturctor"<< endl; }
};
class B : public A // inheritance
{
int b;
public:
B(int b1) // cons (A)
{
b = b1;
}
~B() { cout << "B Disturctor" << endl; } // Dis(B)
};
int main()
{
A hamza(1);
B Ramza(4);
return 0;
}
Output:
B Disturctor
A Disturctor1
A Disturctor2
The first "A Disturctor" is for object "A hamza(1)".
The second "A Disturctor" is for object "B Ramza(4)"
Since B inherits from A, when object of class B is destroyed, destructor of both class B and class A are called.
Related
If I create derived object it calls base constructor first and then derived constructor. Does it mean that parent object also get created when we create derive object?
I don't think parent object gets created, but why does the parent constructor get called?
#include<iostream>
using namespace std;
class A {
public : A(){
cout<<"inside A constructor"<<endl;
}
};
class B : public A{
public : B(){
cout << "inside B constructor" << endl;
}
};
int main() {
B b;
return 0;
}
Output:
inside A constructor
inside B constructor
I don't think parent object get created [...]
You are wrong.
B constists of a A subobject and any members that B has in addition. Consider this example:
struct A {
int a = 0;
};
struct B : A {
B() {}
};
int main() {
B b;
b.a = 42;
}
B inherits the members from A. Those members do not come out of nowhere, but they are part of Bs subobject of type A and that has to be constructed. When you do not call a constructor explicitly then it will be default constructed. The above is roughly equivalent to:
struct A {
int a = 0;
};
struct B : A {
B() : A() {}
// ^^^ call default constructor of A
};
As far as i know, virtual ensures that only one copy of the properties of base class is inherited to the derived class. And in a multiple inheritance the constructor of all base is called first then the constructor of derived is called. In the following code why was the constructor of class B called twice in a row? To my understanding the output should have been
B
B1
B2
D
but the output came out to be
B
B
B1
B2
D
Here's the full code.
#include <iostream>
class B
{
public:
B(){std::cout << "B" << std::endl;}
};
class B1:public B
{
public:
B1(){std::cout << "B1" << std::endl;}
};
class B2:virtual public B
{
public:
B2(){std::cout << "B2" << std::endl;}
};
class D:public B1, public B2
{
public:
D(){std::cout << "D" << std::endl;}
};
int main()
{
D d1;
}
The inheritance of B by B1 must be virtual too.
Virtual inheritance doesn't mean "look in the rest of the hierarchy for an instance of inheritance of this class", it means "use only one instance of inheritance for all virtual inheritances in this hierarchy".
This is the classic "diamond problem" (described here). Your understanding of the virtual keyword is correct, but it only applies if you use it for both B1 and B2.
Write your code like this:
#include <iostream>
class B
{
public:
B(){std::cout << "B" << std::endl;}
};
class B1:public B
{
public:
B1(){std::cout << "B1" << std::endl;}
};
class B2:public B1
{
public:
B2(){std::cout << "B2" << std::endl;}
};
class D:public B2
{
public:
D(){std::cout << "D" << std::endl;}
};
int main()
{
D d1;
}
For instance, I have base class A:
class A {
public:
callA() {
val = 100;
std::cout << this->val << std::endl;
}
int val;
}
class B : public A {
public:
B() {
val = 10;
}
int val;
}
B b;
b.callA();
What will b.callA() print?
And for B inheriting A, if B does not have a field val, will B share an exact reference to A's val, or is it a copy?
Internally, any instance of Class B contains an entire copy of Class A. In fact, when you initialize a new instance of Class B, Class A's constructor is run first. Therefore, when you call a non-virtual function from the base class, it will run as if it were run from the base class, which is internal to the derived class. It can even access the private variables of the base class (which the derived class wouldn't be able to access, it only has access to public/protected variables from the base class).
Example:
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "Base constructor!" << endl;
privateVar = 10;
}
void testPrint()
{
cout << "privateVar: " << privateVar << endl;
}
private:
int privateVar;
};
class B : public A
{
public:
B()
{
cout << "Derived Constructor!" << endl;
}
};
int main()
{
B testB;
testB.testPrint();
return 0;
}
I have a program with a lot of classes. I want classes in the program to be visible to each other. For that, I am following a trick such that all classes are inherited from a base class, which holds pointers to every class. But I hit an error in doing so. Below is a piece of code produces the error I am after:
#include <iostream>
using namespace std;
class AClass;
class BClass;
class RoofClass {
public:
RoofClass();
AClass* a_class;
BClass* b_class;
};
class BaseClass {
public:
BaseClass(RoofClass* roof_class) {
a_class = roof_class->a_class;
b_class = roof_class->b_class;
}
AClass* a_class;
BClass* b_class;
};
class AClass : public BaseClass {
public:
AClass(RoofClass* roof_class) : BaseClass(roof_class) {}
void Afunction();
int Aint = 1;
};
class BClass : public BaseClass {
public:
BClass(RoofClass* roof_class) : BaseClass(roof_class) {}
void Bfunction();
int Bint = 2;
};
void AClass::Afunction() {
cout << b_class->Bint << endl;
}
void BClass::Bfunction() {
cout << a_class->Aint << endl;
}
RoofClass::RoofClass() {
a_class = new AClass(this);
b_class = new BClass(this);
}
int main(int argc, char **argv) {
RoofClass roof_class;
cout << "b calls a" << endl;
roof_class.b_class->Bfunction();
cout << "a calls b" << endl;
roof_class.a_class->Afunction();
}
Roof is the top level class which consists of classes A and B. I want A and B visible to each other. To achieve that, as I said, they both inherit from the Base class. My problem, in particular, is that while B sees A, A does not see B. The reason for this is probably due to the fact that A is initialized before B in constructor of Roof. So, why can I solve this issue?
When RoofClass constructor creates an instance of AClass, it passes a pointer to itself, with uninitialized members a_class and b_class. AClass constructor then copies those values and returns. When RoofClass constructor sets a_class to point to the newly constructed object, the pointers inside AClass are still pointing to nothing.
You probably want BaseClass to store a pointer to RoofClass instead:
class BaseClass {
public:
BaseClass(RoofClass* roof_class) {
r_class = roof_class;
}
RoofClass* r_class;
};
class AClass : public BaseClass {
public:
AClass(RoofClass* roof_class) : BaseClass(roof_class) {}
void Afunction();
int Aint = 1;
// access class B as r_class->b_class
};
I actually solved the question. It is like this:
In its constructor, the RoofClass creates a and b objects, in order. It first initializes a object by going into its constructor (which actually is the constructor of BaseClass due to inheritance) and setting a's a and b objects to roof's a and b. But the problem is that, roof's b is not constructed yet. That is why, a's b is initialized to a value of 00000000. When the RoofClass goes to b object's constructor for initialization, this time both roof's a and b are in place so that b's a and b's b are properly initialized. That is why, b can have a proper a but not vice versa.
The solution is introducing an InitPointer function to the base class, which acts after the roof objects constructs all a and b objects. This way, InitPointer sets pointers of a and b objects to already constructed a and b objects. Here is the working code:
#include <iostream>
using namespace std;
class AClass;
class BClass;
class RoofClass {
public:
RoofClass();
AClass* a_class;
BClass* b_class;
};
class BaseClass {
public:
BaseClass() {}
void InitPointer(RoofClass* roof_class) {
a_class = roof_class->a_class;
b_class = roof_class->b_class;
}
AClass* a_class;
BClass* b_class;
};
class AClass : public BaseClass {
public:
AClass() : BaseClass() {}
void Afunction();
int Aint = 1;
};
class BClass : public BaseClass {
public:
BClass() : BaseClass() {}
void Bfunction();
int Bint = 2;
};
void AClass::Afunction() {
cout << b_class->Bint << endl;
}
void BClass::Bfunction() {
cout << a_class->Aint << endl;
}
RoofClass::RoofClass() {
a_class = new AClass();
b_class = new BClass();
a_class->InitPointer(this);
b_class->InitPointer(this);
}
int main(int argc, char **argv) {
RoofClass roof_class;
cout << "b calls a" << endl;
roof_class.b_class->Bfunction();
cout << "a calls b" << endl;
roof_class.a_class->Afunction();
}
Thanks for the all discussion!
I have a class structure similar to the following
class A
{
public:
A(void);
~A(void);
void DoSomething(int i)
{
std::cout << "Hello A" << i << std::endl;
}
};
class B : public A
{
public:
B(void);
~B(void);
void DoSomething(int i)
{
std::cout << "Hello B" << i << std::endl;
}
};
class Ad : public A
{
public:
Ad(void);
~Ad(void);
};
class Bd : public B
{
public:
Bd(void);
~Bd(void);
};
I want to store instances of the derived classes in a container (standard map) as a collection of A*, then iterate through the container and call methods for each instance.
#include "A.h"
#include "B.h"
#include "Ad.h"
#include "Bd.h"
#include <map>
int main(int argc, char** argv)
{
std::map<int,A*> objectmap;
objectmap[1] = new Ad();
objectmap[2] = new Bd();
for (std::map<int,A*>::iterator itrobject = objectmap.begin();
itrobject!=objectmap.end(); itrobject++)
{
itrobject->second->DoSomething(1);
}
return 0;
}
The above code produces the following output.
Hello A1
Hello A1
Where I was expecting
Hello A1
Hello B1
because I was expecting DoSomething in B to hide DoSomething in A, and because I am storing A pointers, I would expect no object slicing (and looking at the object pointer in the debugger shows that the object has not been sliced).
I have tried down casting and dynamic casting the pointer to B, but it slices away the data members of Bd.
Is there any way to call B::DoSomething without casting the pointer to Bd? And if not, if I have many derived classes of B (e.g. Bda, Bdb, Bdc etc), is there some way to use RTTI to know which derived class to cast it to?
You need to make DoSomething() a virtual function in both classes to get the polymorphic behavior you're after:
virtual void DoSomething(int i) { ...
You don't need to implement virtual functions in every sub class, as shown in the following example:
#include <iostream>
class A {
public:
virtual void print_me(void) {
std::cout << "I'm A" << std::endl;
}
virtual ~A() {}
};
class B : public A {
public:
virtual void print_me(void) {
std::cout << "I'm B" << std::endl;
}
};
class C : public A {
};
int main() {
A a;
B b;
C c;
A* p = &a;
p->print_me();
p = &b;
p->print_me();
p = &c;
p->print_me();
return 0;
}
Output:
I'm A
I'm B
I'm A