Accessing overridden base class member from derived class object - c++

I have two classes:
class A
{
public:
int i;
};
class B : public A
{
public:
int i;
};
Suppose that I created an object for class B
B b;
Is it possible to access A::i using b?

Is it possible to access A::i using b?
Yes!
How about b.A::i? ;)

Yes:
int main()
{
B b;
b.i = 3;
b.A::i = 5;
A *pA = &b;
B *pB = &b;
std::cout << pA->i << std::endl;
std::cout << pB->i << std::endl;
}

Yes you can. To find out read this
An override method provides a new implementation of a member inherited from a base class. The method overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method.
From within the derived class that has an override method, you still can access the overridden base method that has the same name by using the base keyword. For example, if you have a virtual method MyMethod(), and an override method on a derived class, you can access the virtual method from the derived class by using the call:
base.MyMethod()

Two ways:
struct A{
A():i(1){}
int i;
};
struct B : A{
B():i(0), A(){}
int i;
};
int main(){
B b;
cout << b.A::i;
cout << (static_cast<A&>(b)).i;
}

It is possible, as others replied.
But in the example you posted, the base and derived members are the same, the data type was not overriden.
This would be relevant in the case of derived classes that define a new data type for the base members as shown in this post: C++ Inheritance. Changing Object data Types

Related

Accessing virtual base class function from a derived class

1.In the main function below, why does d.foo(9.5) not select the Base::foo(double) method from the base class? Doesn't the derived class inherit that method?
2.What causes the compile error?
class Base {
public:
virtual void foo(int){
cout << "Base::foo(int)" << endl;
}
virtual void foo(double){
cout << "Base::foo(double)" << endl;
}
};
class Derived : public Base {
public:
virtual void foo(int){
cout << "Derived::foo(int)" << endl;
}
};
void main() {
Derived d;
Base b, *pb = &d;
d.foo(9); // selects Derived::foo(int)
d.foo(9.5); // selects Derived::foo(int)
pb->foo(9); // selects Derived::foo(int)
pb->foo(9.5); // selects Base::foo(double)
Derived * d;
d->foo(9); // compile error
}
The compilation error is because of two variables with the same name in main().
As to your problem with inherited functions not being called for an instance of your Derived (except via pointer to Base)
The standard describes the "hiding rule", which makes this happen. Essentially, member functions declared in derived classes hide inherited functions with the same name but different signature inherited from the base class. The hiding rule is independent of whether the inherited functions are virtual or not.
The common solution is to introduce all inherited functions from the base class with using Base::foo. For example,
class Base {
public:
virtual void foo(int){
cout << "Base::foo(int)" << endl;
}
virtual void foo(double){
cout << "Base::foo(double)" << endl;
}
};
class Derived : public Base {
public:
using Base::foo;
virtual void foo(int){
cout << "Derived::foo(int)" << endl;
}
};
Another solution is to remember to explicitly override all inherited versions of the function (implement the derived class version to simply call the base class version of each function). This works with older compilers that do not support a using directive like the above. The catch is that it is necessary to explicitly do this with every inherited overload, and it is easy to miss one.
In the main function below, why does d.foo(9.5) not select the Base::foo(double) method from the base class? Doesn't the derived class inherit that method?
Yes, but it's hidden by the function with the same name in the derived class. You can unhide it with a using-declaration in the derived class:
using Base::foo;
What causes the compile error?
You're trying to declare a second variable called d. Change the name to something that's not already used; and initialise it to point to a valid object, otherwise you'll have a runtime error or other undefined behaviour.
Derived * pd = &d;
pd->foo(9); // selects Derived::foo(int)
Also, main has the wrong return type. It must return int.
1) Because this is exactly how polymorphism work. If a virtual function is redefined in a derived class, this (and only this) redefined version will be called. If the function is not virtual it's vice versa: only the base class function will be called.
//Example 1: non-virtual function
class Base
{
public:
void foo()
{
std::cout << "Base";
}
}
class Derived : public Base
{
public:
void foo()
{
std::cout << "Derived";
}
}
Base * base = new Base();
base->foo()//prints "Base"
Base * derived = new Derived();
derived->foo()//prints "Base", since the function is not virtual, and the version from the base class is called
//Example 2: virtual function
class Base
{
public:
virtual void foo()
{
std::cout << "Base";
}
}
class Derived : public Base
{
public:
void foo()
{
std::cout << "Derived";
}
}
Base * base = new Base();
base->foo()//prints "Base"
Base * derived = new Derived();
derived->foo()//prints "Derived", since the function is virtual, and the redefined version from Derived class is called
2) The compile error happens because you have a conflicting declaration - two objects are called d.
Derived * d;
d->foo(9); // compile error
You don't have instantiated the object:
Derived * d = new Derived;
If you not create the object the compiler use the previous declaration of d: Derived d that is not a pointer.

Base class functions that use derived class variables

In c++, Is there a standard way to create a function in a base class that can use the variables of derived classes?
class Foo{
private:
int x;
public:
Foo(){
x = 2;
}
void print(){
std::cout << x << std::endl;
}
};
class Derived : public Foo{
private:
int x;
public:
Derived(){
x = 4;
}
};
void main()
{
Derived a;
a.print();
}
This code prints the variable of the base class ( 2 ). Is there a way to make a function used by many derived classes to use the class's private variables without passing them as parameters?
Edit: My intentions are, to avoid writing the same code for each derived class.
For example, I want a get_var() in all, but this function should return the variable of that own class. I know I can make virtual and override, but I was looking for a way that I don't need to write again and again.
No, it is not possible for the base class to access anything in the derived class directly. The only way for a derived class to share anything with its base class is by overriding virtual member functions of the base class.
In your case, however, this is not necessary: the derived class can set variable x in the base class once you make it protected, and drop its own declaration as unnecessary:
class Foo{
protected: // Make x visible to derived classes
int x;
public:
Foo(){
x = 2;
}
void print(){
std::cout << x << std::endl;
}
};
class Derived : public Foo{
public:
Derived(){
x = 4;
}
};

Virtual function inheritance

I have a confusion about the inheriting the virtual property of a method.
Let's suppose we have 4 classes: class A, class B, class C and class D.
The classes are inherited by this way: A -> B -> C -> D, where A is the base class.
By this time, I'm sure about this: Beginning the class method declaration with virtual in a base class (class A), makes the method virtual for all classes derived from the base class, including the derived ones of the derived classes. (B and C class methods determined to be virtual).
The confusion is here. What if, in the base class A, there wouldn't be any virtual member. Instead, let's say, that class B declares a method to be virtual. I assume, that this change would make the function virtual for all the derived classes that belong to the inheriting chain (C and D classes). So logically, B for C and D, is a sort of their "base class", right? Or am I wrong?
You're correct.
I think that in this case the best solution is to try:
#include <iostream>
using namespace std;
class A {
public:
void print(){ cout << "print A" << endl; };
};
class B: public A {
public:
virtual void print(){ cout << "print B" << endl; };
};
class C: public B {
public:
void print(){ cout << "print C" << endl; };
};
int main()
{
A *a = new C();
B *b = new C();
a->print(); // will print 'print A'
b->print(); // will print 'print C'
return 1;
}
You are entirely correct. Child inherits what its ancestors have. Base classes can't inherit what the child has (such as a new function or variable). Virtual functions are simply functions that can be overridden by the child class if the that child class changes the implementation of the virtual function so that the base virtual function isn't called.
A is the base class for B,C,D. B is a the base class for C, D. and C is the base class for D too.
Of course you can do it. Virtual method is optional to override so it doesn't matter that you declare it in class A or B. If you dont want to use that method in class A then simply declare in in class B.

Do private elements in the base class add to the size of the derived class?

// inheritence experiment
#include"stdafx.h"
#include<iostream>
using namespace std;
class base
{
private:
int i;
};
class derived: public base
{
private:
int j;
};
int main()
{
cout << endl << sizeof(derived) << endl << sizeof(base);
derived o1;
base o2;
cout << endl << sizeof(o1) << endl << sizeof(o2);
}
I'm getting this output:
8
4
8
4
why's that so? private data members of a base class aren't inherited into the derived class, so why I am getting 8 bytes for both, the size of derived and o1 ?
Private members are inherited. You just cannot access them from your derived class.
The private members are actually in the derived class, they're just not accessible within the derived class. The private keyword is to prevent programmers that derive from the base class from changing values the designer of the base class didn't want you to change because it might alter the functionality of the base class.
Have a look here for a deeper explanation
Fragile base class
class base {
public:
base(int v) : m_value(v) { }
int value() { return m_value; }
private:
int m_value;
};
class derived : private base {
derived(int v) : base(v) { }
int value2() { return value(); }
};
int main()
{
derived d(2);
return d.value2();
}
How do you expect this to work if the private base class doesn't store the value somewhere?
Your choice of words "inherited into the derived class" makes me think you are confused about how inheritance works. Members from the base class are not inherited into or copied into the derived class. The derived class contains an instance of the base type, as a sub-object within the complete derived object, so a derived class is (usually) at least as large as the sum of its base classes.
Consider this code:
struct A {
private:
int i;
};
struct B {
int j;
};
struct derived : A, B {
int k;
};
An A object is laid out in memory as an int, and so is a B.
A derived object could be laid out in memory as an A object, followed by a B object, followed by an int, which means it is a sequence of three ints. Whether the base class members are public or private doesn't affect that.
Of course they are inherited -after all, the behavior of the base-class will probably depend on them being there-, they are just not accessible!
Inherited methods of the base class can still use the private memebers. They have to be there.

Inherited member function accessing data members

Consider the sample code below:
#include <iostream>
using namespace std;
class A
{
private:
static int a;
int b;
protected:
public:
A() : b(0) {}
void modify()
{
a++;
b++;
}
void display()
{
cout << a <<"\n";
cout << b <<"\n";
}
};
int A::a=0;
class B : public A {
private:
int b;
public:
B(): b(5)
{
}
};
int main()
{
A ob1;
B ob2;
ob1.display();
ob2.display();
return 0;
}
In the code above, the class A has a private data member band class B also has a private data member b. The function display() is used to display the data members.
When i invoke display() using ob1.display(), display() accesses the private data member b of class A. I understand that. But when i invoke display using ob2.display, which b does display() access? Is it the b of class A or b of class B? Kindly explain the why it accesses class A's b or class B's b
It will access A::b. The display method implementation in class A has no clue about the existence of B::b at all, let alone using it. For all intents and purposes, B::b is separate from A::b. Only in the scope of B itself, the name conflict makes b refer to B::b, hiding A::b. Member variables cannot be virtual.
ob2.display() will access the derived class member.
The member function call is always evaluated on this, this->display() the this in case points to object of your Base class and hence any reference to b inside the display() function is evaluated as this->b which is b of the Base class.
This is because display() of the Base class has no knowledge of whether any other class derives from it. Base class is always independent of the Derived class. To solve a problem the uual pattern followed is to provide a display() method in the Derived class which then in turn calls the dsiplay() method of the Base class.
void B::display()
{
//cout << a <<"\n";
cout << b <<"\n";
A::display();
}
It is class A. A::display() cannot access B private members.