using derived class data members from base class method - c++

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.

Related

change value of data member of one class from another class

#include <iostream>
using namespace std;
class B{
public:
int x;
void setx(int a){
x =a;
cout<<"Inside set "<<x<<endl;
}
void show();
};
void B::show(){
cout<<"inside show "<<x<<endl;
}
class A{
public:
void func();
void func2();
B bb;
};
void A::func(){
bb.setx(100);
bb.show();
}
void A::func2(){
bb.show();
}
int main()
{
A a;
B b;
a.func();
b.show();
a.func2();
return 0;
}
Changes are applicable only to class A, where actual value in class B is not changing. I tried static but its showing error.
OUTPUT I'M GETTING :
Inside set 100
inside show 100
inside show 0
inside show 100
OUTPUT I WANT :
Inside set 100
inside show 100
inside show 100
inside show 100
Try:
int main()
{
A a;
B b;
a.func();
a.bb.show();
a.func2();
return 0;
}
You're calling show() on wrong object. Since a has it's own bb, you need to use a.bb to see change. b in main is different object (even if of the same class).
A class is not an object. It is a user defined data type which can be accessed and used by creating an instance of that class. An instance of the class is an object.
Now, in your main function, when you instantiate an object of class A by writing A a;, the constructor of class A instantiates the data member bb (which is of type B). You then create another object of type B in your main function, by writing B b;. This instantiation of class B has nothing to do with the data member bb in your class A. To get your desired output, you would need a.bb.show().
To be clear:
struct Airplane {};
Airplane a1, a2, a3;
I have 3 airplanes, which are each an instantiation of the class Airplane, 3 objects of type Airplane. Changing a1 doesn't imply changing a2 and a3.

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.

Override Function in Member Object

Disclaimer: I'm a long time C programmer moving into C++, so it's very likely/possible there is a better way to do this.
I would like to create a class A with 1 to N members of class B. In most cases, I'm fine calling class B's member functions. However, in some cases I would like to override a member function in class B. Is there an elegant way to do this without having to create a derived class from class B every time?
Here is an example:
using namespace std;
#include <iostream>
class B
{
public:
void print();
};
void B::print()
{
cout << "B::print" << endl;
}
class A
{
public:
B b;
B bprime;
};
int main()
{
A a;
a.b.print();
a.bprime.print();
return 0;
}
Is there a way to override the print() function in bprime or otherwise change it? In C, I would have left class B as a struct and used function pointers, but I'd like to avoid that here.
You can use std::function to simulate polymorphism.
class B
{
public:
std::function<_FUNCTION_SIGNATURE_HERE_> print;
};
then you can always override print member in an instance of B
a.bprime.print = SomeOTherFunctionWithSameSignature;
and from this moment on bprime will behave as if it was a different subclass in a hierarchy. Everything will work the same, except this particular function you changed.
Of course you will have to set initial behavior of print member in your constructor.

Member variable hiding in derived class

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.

OOPS Memory Allocation for Base class under Inheritance?

Program:
class A
{
int a;
public:
void geta()
{
a=10;
}
void puta()
{
cout<<"a : "<<a;
}
};
class B : public A
{
int b;
public:
void getb()
{
geta(); b=20;
}
void putb()
{
puta(); cout<<"b : "<<b;
}
};
int main()
{
B ABC;
ABC.getb();
ABC.putb();
return 0;
}
The Problem:
The above program allocates memory for derived class object & calls its relevant methods.
The base class is inherited as public, and as the variable 'a' is a private member, it will not get inherited.
So, the program should not allocate memory for this variable.
But, when the above is executed, 'a' variable will be allocated even though it is not inherited.
Could anyone help me understand this?
Thank You.
as the variable 'a' is a private member, it will not get inherited. So, the program should not allocate memory for this variable.
Your assumption is mistaken. Public inheritance models an "is-a" relationship. That is, class Derived is-a Base. Anything you can do with a Base, you should be able to do with a Derived. In order for this to be true, it necessarily must contain everything that Base contains.
In your example, it's perfectly legal to say:
B b;
b.put_a();
that is, to use A methods on B object. This would not work if the a member was absent.
The base class is inherited as public, and as the variable 'a' is a private member, it will not get inherited.
When a base class member is declared as private it doesn't mean it does not get inherited. It just means that the member variable will be inherited (will be part of the derived class) but won't be accessible.
For example, in:
class A {
private:
int a;
int b;
// ...
};
class B : public A {};
auto main() -> int {
B b;
}
When we allocate B b; we are allocating both a and b member objects of the class A.
The variable a is inherited, though you have no access to it. For example, the following code would work:
class A {
private:
int x;
public:
int getXfromA() { return x; }
};
class B : public A {
public:
int getXfromB() { return getXfromA(); }
};
However, x cannot be directly accessed from B class here.
You're confusing storage with access control.
If object B inherits from object A, it has all of object A's methods and members, even if it cannot access them directly.
The purpose of private and protected is access control. If you mark members and methods as private, then nothing outside can access those methods and members. But, those things are part of the object nonetheless.
This allows you to implement class invariants without exposing the details, including classes that inherit from the base.
Here's an example that encapsulates capturing the creation time of an object in the base class:
#include <time.h>
#include <iostream>
class Base
{
private:
time_t create_time;
public:
Base()
{
create_time = time(0);
}
time_t get_create_time() { return create_time; }
};
class Derived : public Base
{
public:
Derived() { }
};
int main()
{
Derived D;
std::cout << D.get_create_time() << std::endl;
}
Derived doesn't know or need to know how the creation time was captured. It's a class invariant it inherited by deriving from Base.
This is a pretty simple example, but you could imagine more complex examples.