Member variable hiding in derived class - c++

This is the code I have. Base class has member variable i and derived class also has same member variable name. Now client creates Base ptr pointing to derived and accesses member variable directly using i. I thought it would call derived member variable, instead it calls base class variable. I am not sure why this is?
#include<iostream>
using namespace std;
class A{
public:
int i;
A(int ii=5):i(ii){}
virtual void display(){
cout<<" In A :"<<i<<endl;
}
};
class B: public A{
public:
int i;
B(int ii=7):i(ii){}
void display(){
cout<<" In B :"<<i<<endl;
}
};
int main(){
A * aptr = new B();
cout << aptr->i <<endl; // expected B::i but gave A::i
aptr->display();
B bb;
bb.display();
return 0;
}
Is there a good reason for this. I thought like vptr is member variable of object(when new B was called) and this vptr calls correctly when we type aptr->display. Why isn't the same thing happening with i.

Member variables in C++ are not shadowed by inheritance the way virtual functions are.
If B inherits from A, and they both define a member named i, both of those variables exist and are independently part of the object.
Since your pointer has the type A*, the expression aptr->i will resolve to A's version of i.
As a side note, B can also explicitly access A's version of i, as long as it is not private.
class B: public A{
public:
int i;
B(int ii=7):i(ii){}
void display(){
cout<<" In B :"<<i<<endl;
cout<<" In A :"<<A::i<<endl;
}
};

This is what I wanted to ask and luckily was able to write in main func the stuff i needed.
Please check and let me know why A& and A instance behave differntly.
int main(){
A * aptr = new B();
cout << aptr->i <<endl;
aptr->display();
B *bptr = dynamic_cast<B*>(aptr);
bptr->display();
cout << bptr->i <<"\t" <<bptr->A::i<<endl;
A & aref = static_cast<A&>(*aptr);
cout <<endl <<"Called ref : "<<aref.i<<endl;
aref.display(); // here it calls B::display
A aa(*aptr);
cout <<endl <<"Called Inst : "<<aa.i<<endl;
aa.display(); // here it calls A::display
delete aptr;
return 0;
}
Question is why aref and aa behave differently?
My understanding is when instance of B was created using new B(). there were 2 variables in it, "i" and vptr of class B.
When aref is created, it called vptr of B for display,
but aa calls A::display,
While for both cases slicing is happening then how does it behave differently.
I am asking question in terms of memory is allocated to any class instance and when ptr of base is pointing to derived class. Hope you understand my confusion.

Related

using derived class data members from base class method

So i have been trying to use derived class data members from the base class and i am not able to figure out how to do that. I see a way to do this as just passing the member i need in parameter when i call the base class method but i was just thinking that there should be another way to do that. So i have replicated this as below.
#include<iostream>
using namespace std;
class B;
class A{
public:
display(){
cout<<cord<<endl;
}
int cord = 25;
};
class B : public A{
public:
B(){
A a;
a.display();
}
int cord = 30;
};
class C : public A{
public:
C(){
A a;
a.display();
}
int cord = 35;
};
int main(){
B b;
C c;
B.display();
}
The above code as giving output as
25
25
25
What i want it to give out is
30
35
30
Every way to do this will be appreciated, whatever is better and if you want to me add something or anything ask in comments, i'll do right away.
define a virtual getter like
virtual int getCord() const { return cord; }
in each class and call it in display
void display(){ cout << getCord() <<endl; }
and in the constructor of B and C you also need to replace
A a;
a.display();
just by
display();
else there is no chance you access to the value of the sub classes explicitly calling display on an instance of A
using derived class data members from base class method
This is because of that I let the redefinition of cord in B and C, but I do not recommend you to do that kind of redefinition in 'real' codes ;-)
Lets take the B constructor:
B(){
A a;
a.display();
}
In it you create a completely separate object a of type A, and call display on it. That display call will be using the a object, not knowing anything about the B class or its totally separate cord member variable at all.
One possible way to solve this is to create a constructor of A that takes the value of cord as an argument, pass the "correct" value in the B constructor initializer list, and then call the display function on this object:
struct A{
A() = default;
explicit A(int c)
: cord(c)
{
}
display(){
cout<<cord<<endl;
}
int cord = 25;
};
struct B : A{
B()
: A(30)
{
display(); // Equivalent to this->display();
}
};
Of course, you need to do something similar for the C class (or structure).
Note that I removed the member variable cord from the B class. That's because if you declare a new member variable with the same name as a member variable in a base class, then you effectively create a completely new member variable that is unrelated to the one in the parent class. And for the simple example you show there's no need to "override" the member variable, as it already exists in all child-classes as well.

I try understand How how method Overriding work, couldn't figure why is outputting 2

Here is the code
,it is my homework using overriden methods teacher told us to analyze the code. I know the code is outputting 2, I have no clue how this code work.
public:
int a;
virtual void who(void) { a = 1; }
};
class B:public A{
public:
int a;
void who(void) { a = 2; }
};
class C :public B {
};
int main(void) {
A x; B y; C z; A *p;
p = &z;
p->who();
cout << z.a << endl;
system("pause");
return 0;
}
B overrides the who() function of its parent, A. This is called polymorphism. C inherits from B, but doesn't override anything; thus, it uses all of the implementation of B.
p is a pointer to an object of class A. One of the key features of class inheritance is that a pointer to a derived class is type-compatible with a pointer to its base class [1].
This means that when you call a member function of a pointer (p->who()), and the class of the object the pointer is pointing to overrides a member of its parent, is going to use the overridden member.
Sources:
[1] http://www.cplusplus.com/doc/tutorial/polymorphism/
as long as you create a function with same input and output with name; in short: same function declaration.. the new one will be used as you refer to one which has super class that has same function. in your case; super class for C is B and it doesn't see A, but B sees A and use all functions it has except what's B declare a new implementation for.

c++ : How to bind inherited methods only to parent classes?

i've stumbled upon this problem while doing multi-base inheritance project for my college work. Example of my problem, and code itself: I'm setting up 3 classes, A, B and C.
B inherits publicly from A.
C inherits publicly from B.
I want to set a method publicly in B, that does take as argument a pointer to an object of class A. However it should be able to use only class A objects, neither B or C.
Problem is that Visual Studio 2013 doesn't show any error, and simply allows for my method to be used by B class object on a C class object, which is exactly the opposite of what i want to achieve. Why is that happening?
Does that mean that inheriting somewhat makes C object being interpreted as of type A, B and C at the same time? If not, is there a direct way to bind a method to be used only on classes that it inherits from (c methods on both A and B objects)? Feel free to correct me if i'm wrong anywhere, i'm still a newbie at programing. Thank you for your help! `
class A
{
private:
int x;
string z;
public:
void SetZ()
{
cout << "Set Z: ";
cin >> z;
}
string GetZ()
{
return this->z;
}
};
class B
:public A
{
public:
void use_base(A* k)
{
cout << "here and now, i'm using " << k->GetZ() << " however i, " << this->GetZ() << ", might want to!";
}
};
class C
:public B
{
void use_base(A* k)
{
cout << "extra";
}
};
int main()
{
A Bob;
B Mark;
Bob.SetZ();
Mark.SetZ();
C Karl;
Mark.use_base(&Karl); // doesn't show any error
return 0;
}`
If B inherits publicly from A, then B* can be implicitly converted to A* so a function that takes A* can be called with B* arguments. To prevent this, you could make the inheritance protected or private. However, that might create other problems.
To prevent accidentally passing a B*, you can declare another overload that takes B* and delete it. This overload will win for B* and C* arguments and cause a compilation error. You can also generalize this approach using templates, and so prevent passing a pointer to any class derived from A, without naming all such classes.
void use_base(A* k) { /* do something */ }
void use_base(B*) = delete;
However, that doesn't stop someone from explicitly casting a B* or C* to A* and calling the A* overload.

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;

c++ inherit virtual functions

ok say we have the following classes
class A
{
public:
virtual void taco()
{
cout << "Class A" << endl;
}
};
class B: public A
{
public:
virtual void taco()
{
cout << "Class B" << endl;
}
};
class C : public A
{
public:
void taco()
{
cout << "Class C" << endl;
}
};
Now if I do this
A a = A();
B b = B();
C c = C();
a.taco(); //Class A
b.taco(); //Class B
c.taco(); //Class C
deque<A> aa = deque<A>();
aa.push_back(a);
aa.push_back(b);
aa.push_back(c);
for(int i=0;i<aa.size();i++)
aa[i].taco();//All Class A
A r = B();
r.taco(); //Class A
Now you'll notice when I initialize A as B or C, it won't fire the functions from B or C. I was wondering if there was any way around this? I understand the concept that since the object is A it uses A's taco function, but I was just wondering if there was some trick to getting at the other functions. My project is fairly complicated, and I can't know all the classes that will override A(due to plugins overriding a class). Also, I kinda need to have the base virtual function have a body to add default behavior. Thanks.
You must store pointers in the deque, since polymorphism only works with reference & pointer types. When you insert those objects into the deque, copies are made of type A, "slicing" off the parts that made them B or C originally.
Similarly, A r = B() just creates a temporary B and copies the A part of it into an A called r.
BTW by A a = A(); you might as well write A a;. They're not completely equivalent, but they do the same job here, and you likely meant for the simpler version.
A a;
B b;
C c;
a.taco(); //Class A
b.taco(); //Class B
c.taco(); //Class C
// With pointers and containers
deque<A*> aa;
aa.push_back(&a);
aa.push_back(&b);
aa.push_back(&c);
for (int i=0; i<aa.size(); i++)
aa[i]->taco(); // Hurray!
// With refs
B q;
A& r = q;
r.taco(); // Class B!
(Just remember that those objects a, b and c have automatic storage duration. The moment they go out of scope, if the deque still exists then all its elements are invalid pointers. You may want to employ dynamic allocation to further control the lifetime of the A, B and C objects.. but I'll leave that as an exercise to the reader.)