c++ inheriting. getting data members value of base class - c++

class A
{
public:
A(int a, int b, int c)
:x(a), y(b), z(c)
{}
void display()
{
cout << "x is " << x << endl;
cout << "y is " << y << endl;
cout << "z is " << z << endl;
}
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
public:
B(int x, int y, int z, int extra)
: A(x, y, z), num(extra)
{}
void display()
{
cout << "x is " << x << endl;
cout << "y is " << y << endl;
//cout << "z is " << z << endl;
}
private:
int num;
};
int main()
{
A yo1(1,2,3,);
B yo2(4,5,6,100); //<---
yo2.display(); //I want to print 1 2 3 100
return 0;
}
I have a simply inheritance here. Using inheritance, I want to get A's values and put it into B. How do I access the values of its data members from class A by created a B object? I created an object of class A and gave them the value 1,2,3. In the end, I want to print 1 2 3 100 by using class B's display function.
I understand how I can use the variables from class A but can I also grab their values?

you are confused with concept of inheritance,
B yo2(4,5,6,100);
during this there is separate copy of base class created for the object yo2 which has nothing to do with the object yo1
A yo1(1,2,3,);
the data members x,y,z will have 1,2,3 for yo1 and 4,5,6 for yo2
if you want the output to be
1 2 3 100
then create the object as :
B yo2(1,2,3,100);

you can modify your derived class as
class B : public A
{
public:
B(A& obj, int extra)
: A(obj.x, obj.y, obj.z), num(extra)
{}
void display()
{
A::display();
cout << "num is " << num << endl;
}
private:
int num;
};
and in main you can access as
int main()
{
A obj(1,2,3);
B objB(obj,100);
objB.display();
}

I think you might have misunderstood inheritance.
There is no way for yo2 to know about the values you have given to yo1.
The values yo2 have in A's variables are 4,5,6 respectively.
to illustrate inheritance a little you could rename the display methods "display_a" and "display_b" and then you could access them thus:
yo1.display_a(); // OK. prints values 1,2,3
yo1.display_b(); // Compile error.
yo2.display_a(); // OK. prints values 4,5,6
yo2.display_b(); // OK. prints values 4,5 from variables inherited from A.
To get what happens with the two "display" methods in your original code, look up overloading and the key-word "virtual". Also look up the operator ::
I hope this helps.

First, I think you have misunderstood what inheritance means and yo1 has nothing to do with yo2 at all. Second, you want to use B display function to display A object's members but you are lazy to construct B with argument 1,2,3 because A has constructed using those. Because A's y is protected and A's z is private, you must use a way to copy A object's members to B object if you want achieve your goal. So I think the rajenpandit's answer is right and useful for you.

Related

Unexpected output value with class constructor and class member variable

I need to understand why x(x + 1) happened only after I get out of the constructor.
class A
{
protected:
int x;
public:
A(int x = 5) : x(x + 1)
{
cout << "In A::A x=" << x << endl;
}
operator int() const { return x; }
};
void main()
{
A a1(10);
cout << a1 << endl ;
}
I was thinking I will get:
In A:: An x=11
11
But somehow I've got:
In A:: An x=10
11
You have two variables named x.
Inside the body of the constructor the argument variable will shadow the member variable. Whenever you use x inside the body of the constructor, it will be the argument, not the member.
To use the member variable you need to explicitly fetch it from the object, like this->x.
General tip: Don't use the same name for symbols in nested scopes. Besides solving this problem, it will also make the code easier to read and understand.
Your parameter is hiding the member variable of the same name - your definition is equivalent to
class A
{
protected:
int y;
public:
A(int x = 5) : y(x + 1)
{
cout << "In A::A x=" << x << endl;
}
operator int() const { return y; }
};
When a parameter has the same name as a member, you need to explicitly refer to the member with this->.
(The initialiser list follows its own rules.)

(C++ inheritance) storing objects with common parent in stl container

I am storing an objects with common parent in stl container (actually stack), but calling a virtual function on object inside of it results in calling an implementation in this common parent. See demo code:
#include <iostream>
#include <stack>
using namespace std;
class Z
{
public:
virtual void echo()
{
cout << "this is Z\n";
}
int x;
};
class A: public Z
{
public:
virtual void echo()
{
cout << "this is A\n";
}
};
int main()
{
A a;
a.x = 0;
Z z;
z.x = 100;
stack<Z> st;
st.push(a);
st.top().echo(); // prints "This is Z"
cout << "x = " << st.top().x << endl; // prints 0
st.push(z);
st.top().echo(); // prints "This is Z"
cout << "x = " << st.top().x << endl; // prints 100
return 0;
}
In general, containers of objects and polymorphism don't mix : You are slicing your objects of type A into objects of type Z when you push them in the container (because the container is really expecting and storing objects of sizeof(Z))
Use std::stack<Z*>, or std::stack<std::unique_ptr<Z>> to manipulate pointers to your base class.
See also : What is the slicing problem in C++?
You have slicing:
You should use std::stack<Z*> or std::stack<std::unique_ptr<Z>>.
What you observe is slicing. Your stack stores Z objects, so even if you construct an A object, it will not be stored in the stack - an Z object will be constructed from A and stored.
You cannot store in container by value if you want polymorphism. Use stack<unique_ptr<Z>>.

Working of nested class objects?

I am trying to understand the order of exectution of a class which has nested objects of another class inside it. Here's my simple program :
#include<iostream>
#include <string>
using namespace std;
class Alpha
{
int a;
public:
Alpha(int x)
{
a=x;
}
};
class Beta
{ int b;
public:
Beta(int y)
{
b=y;
}
};
class Gamma
{
Alpha A;
Beta B;
int c;
public:
Gamma(int a,int b, int d): A(a), B(b)
{
c=d;
}
};
void main()
{
Gamma g(5,6,7);
}
As you can see, Gamma has 2 nested objects. Now when the first line of main() is executed, how does the execution start inside the class Gamma? The constructer is called first or the objects/data-members are created first?
The question of constructor execution order is simple: first, Gamma constructor starts, but then it immediately proceeds to initializing Alpha and Beta, as specified in your initialier list. Once the intializer list is done, the body of Gamma's constructor is executed.
There is an important twist to this: C++ will initialize nested objects in the order in which they are declared in the class, not in the order in which they are listed in the initializer list. In other words, Alpha will be initialized ahead of Beta even if you reverse A(a) and B(b):
// The compiler will issue a warning for this
Gamma(int a,int b, int d): B(b), A(a)
{
c=d;
}
The constructer is called first or the objects/data-members are created first?
From an initializer list the members or base class constructor calls are executed before the constructors body of the containing / inherited class.
You can easily check what's going on placing some output statements in the constructors
Alpha(int x) {
cout << "a = " << a << std::endl;
a=x;
cout << "Alpha(" << a << ")" << std::endl;
}
Beta(int y) {
cout << "b = " << b << std::endl;
b=y;
cout << "Beta(" << b << ")" << std::endl;
}
Gamma(int a,int b, int d): A(a), B(b) {
cout << "c = " << c << std::endl;
c=d;
cout << "Gamma(" << c << ")" << std::endl;
}
Output is
a = 0
Alpha(5)
b = 134514731
Beta(6)
c = -1218371596
Gamma(7)
See here for a fully working sample.
Objects in the initialization list are initialized first. Then, the body of the constructor inside {} is executed.

Why is accessing private variable allowed here?

I have this class declared. I observed that in the method distance(Point b), how is it possible to access the private members of Point - b.x and b.y? If I try to access b.x and b.y in main, it is not allowed.
#include <iostream>
#include <cmath>
using namespace std;
class Point {
private:
int x, y;
public:
Point() {
cout << "Constructor called" << endl;
x = 0; y = 0;
}
~Point() {
}
void set(int a, int b) {
x = a;
y = b;
}
void offset(int dx, int dy) {
x += dx;
y += dy;
}
void print() {
cout << "(" << x << "," << y << ")" << endl;
}
// HERE
double distance(Point b) {
return (sqrt(pow(x-b.x, 2)+pow(y-b.y, 2)));
}
};
int main() {
Point p, q;
p.print();
p.offset(4, 3);
p.print();
q.set(10, 2);
cout << "Distance: " << p.distance(q) << endl;
return 0;
}
NOTE: I have compiled and ran the program on ideone.com
The concept of access specifiers such as private, public etc. applies to classes, not just objects of classes. If a variable is private in a class, and an object A of that class has a function that takes another object B of the same class, A has access to B's private members since A and B belong to the same class.
Copy constructors rely on this:
#include <iostream>
using namespace std;
class A {
public:
A(){val = 1.0;}
//copy constructor
A(const A& _other) {
val = _other.val; //accessing private member of _other
}
double dist(A _a) {return val - _a.val;} //accessing private member of _other
private:
double val;
};
int main() {
A a;
A b;
cout << a.dist(b) << endl;
}
int x, y; are private to the Class Point. It means all the members of Class Point can access,modify it.
The functions and constuctors of Class Point are public i.e Other functions(from some other class etc) [like main] can access them. The idea of OOPS is to keep your data safe, Anyone who wants to modify the values can do it via the public methods of that class. They can't access them directly. This allows you to keep any check for invalid modifications to data [setting invalid values like height = -4; etc]
If u keep int x,y as public [which is not correct OOPs] any function (main etc) can access it and modify the value to something undesirable.
Point p;
p.x = -5 (suppose you only wanted +ve values for x , you can't check if the functions accessing is setting some undesirable value)`
Not a relevant analogy , but still...You have a room in the house which only the family members can access. Any outsider who wishes to keep or remove or do anything to the things in the house has to ask your family members to do it. If u assume even family members are not allowed to access the room [assuming even member functions can't access variables ] then there is no use of keeping anythin in the room [the data cannot be used by anyone]

Inheritance: why is there a difference in behaviour between inherited and supplied variables?

For example, in this piece of code, if line [a] is commented out, the output is 0.
inh2.cpp
#include<iostream>
using namespace std;
class A {
public:
int x;
A() { x = 10; }
};
class B : public A {
public:
int x; // <--------- [a]
B() { x = 0; }
};
int main() {
A* ab = new B;
cout << ab->x << endl;
}
results from gcc
$ g++ inh2.cpp
$ ./a.out
10
$
I have two questions:
How does ab->x resolve to 10 in the above case? The object is of type class B, and thus should value to 0.
Why does commenting Line [a] change the behaviour of the code? My reasoning is that x would have anyways been inherited, which should result in same behaviour.
My reasoning for Q #1 above:
ab points to the memory location of an object of class B. It is a physical object in the sense that all the variables with their values are assigned memory.
Variable x within this object stores value 0.
When ab->x is done, ab tells us the memory location of the object, and we go look inside it to find that x is 0. So we should print 0.
Where am I wrong here?
Yes, it is of type B, but you are assigning it as a pointer to an A, and therefore it is using the x defined on A (as when we're dealing with a pointer to A, we don't know that B even exists, even though that's what you allocated).
When you comment out the line, during the construction phase, As constructor is called first, then Bs constructor, which sets x (in its base class) to 0. There is only one x at this point, and Bs constructor is called last.
Making a some small modifications:
#include <iostream>
using namespace std;
class A {
public:
int x;
A()
:x(10)
{
std::cout << __FUNCTION__ << std::endl;
std::cout << x << std::endl;
}
virtual ~A() {}
};
class B : public A {
public:
int x; // <--------- [a]
B()
:A()
,x(0)
{
std::cout << __FUNCTION__ << std::endl;
std::cout << x << std::endl;
}
};
int main() {
A* ab = new B;
cout << "ab->x: " << ab->x << endl;
cout << "ab->A::x " << ab->A::x << endl;
B* b = dynamic_cast<B*>(ab);
cout << "b->x: " << b->x << endl;
cout << "b->A::x " << b->A::x << endl;
cout << "b->B::x " << b->B::x << endl;
}
This gives you:
A
10
B
0
ab->x: 10
ab->A::x 10
b->x: 0
b->A::x 10
b->B::x 0
This demonstrates that:
ab->x refers to A::x because ab is of type A* and there is no such thing as a virtual variable. If you want polymorphism, you'll have to write a virtual int get_x() const method.
B::x hides A::x. This is a bad idea and should be avoided. Consider using a more meaningful name for your member variables and establish whether you can reuse the base class's variable before introducing a new one.
Casting to a B* allows you access to B's members as well as A's. This should be self-explanatory.