Inheritance of pure virtual function - c++

Consider the following code:
#include <iostream>
using namespace std;
class Parent{
virtual void print() = 0;
};
class Derived : public Parent {};
int main() {
Derived d1;
return 0;
}
My doubt over here is that, print function in the parent class is a private member function, then how does it get inherited in the derived class?

Related

Calling a function that takes a pointer to the base class using pointer to a derived class that inherits the base class privately

If you attempt something like this:
#include <iostream>
using namespace std;
class Base {
};
class Derived: private Base {
};
void sayHello(Base* base) {
cout << "Hello" << endl;
}
int main()
{
Derived *derived_ptr = new Derived();
sayHello(derived_ptr);
return 0;
}
You get this compilation error:
main.cpp: In function ‘int main()’:
main.cpp:24:13: error: ‘Base’ is an inaccessible base of ‘Derived’
24 | sayHello(derived_ptr);
|
~~~~~~~~^~~~~~~~~~~~~
Which is expected.
But if I call the sayHello function from within in the derived class, somehow this seems to be working.
#include <iostream>
using namespace std;
class Base;
void sayHello(Base* base) {
cout << "Hello" << endl;
}
class Base {
};
class Derived: private Base {
public:
void derivedClassSayHello() {
sayHello(this);
}
};
int main()
{
Derived *derived_ptr = new Derived();
derived_ptr->derivedClassSayHello();
return 0;
}
Can someone explain why the second example works?
I don't know what is happening here, but by following the second example, I am able to use private members of the Derived class in the sayHello function.
#include <iostream>
using namespace std;
class Base {
public:
int x;
Base(int xx) : x(xx) {
}
};
void sayHello(Base* base) {
cout << "Hello " << base->x << endl;
}
class Derived: private Base {
public:
Derived() : Base(10) {}
void derivedClassSayHello() {
sayHello(this);
}
};
int main()
{
Derived *derived_ptr = new Derived();
derived_ptr->derivedClassSayHello();
return 0;
}
Output:
Hello 10
This is simply because derivedClassSayHello() is a member of its class, and therefore has access to its private members or base classes.
That is precisely what private inheritance means: only members of the class have access to other private members.
It is the caller that attempts to perform the conversion from the derived class to the base class. And since the caller is a member of a class it has full access to its private members.

Why is the inherited function inaccessible?

A small example to reproduce the error in Visual Studio (Community) 2022:
#include <iostream>
#include <memory>
class Base {
public:
virtual void b();
protected:
std::string Method() {
return "Base::Method";
}
};
class SubA : public Base {
public:
// Prevent compiler from optimizing class away.
int doSomething() {
return 7;
}
};
int main() {
SubA sa;
sa.doSomething();
sa.Method(); // <-- Function is inaccessible.
}
Why is the error? The inheritance is public and I'm calling Method on an object from the SubA class.
The inheritance is public
But the member function is protected. You're accessing the member function from main which is outside of the scope of the class or its decendants, so it has no access to protected member functions.

Why object of derived class d cannot call the protected member function of the class base?

Here the object of derived class d cannot call the protected member function of the class base.
#include <iostream>
using namespace std;
class base
{
protected:
int i,j;
void setij(int a,int b)
{
i=a;
j=b;
}
void showij()
{
cout<<i<<" "<<j<<endl;
}
};
class derived : protected base
{
int k;
public:
void show()
{
base b;
b.setij(10,20);
b.showij();
}
};
int main()
{
base b;
derived d;
d.setij(3,4);
d.showij();
d.show();
return 0;
}
I expect the output is 10 20, but the compiler is showing error.
You used protected inheritance. The problem is not that the derived cannot access protected methods of the base, but the problem is that you cannot access base methods from outside of derived.
If you don't know what protected inheritance means you can read eg here Difference between private, public, and protected inheritance
I doubt you wanted to use protected inheritance here (why would you?). Change it to public inheritance and your code should be fine:
class derived : public base ...
PS: The error message should have told you what is the actual problem (albeit in a cryptic way). Please next time include it in the question. If you cannot understand it, probably others will.
There is a lot wrong with this code. Even if you change the inheritance of class derived from protected to public, the following problems still exist:
In class derived, statements b.setij(10,20); and b.showij(); will still generate compiler errors. See Why can't a derived class call protected member function in this code? for a good explanation. The short explanation: a method can only call a protected method in a base class on the object for which it was originally invoked.
Function main will not be able to call d.setij(3,4); or d.showij(); because these are protected methods in class base.
This should run:
#include <iostream>
using namespace std;
class base
{
protected:
int i,j;
void setij(int a,int b)
{
i=a;
j=b;
}
void showij()
{
cout<<i<<" "<<j<<endl;
}
};
class derived : public base
{
int k;
public:
void show()
{
this->setij(10,20);
this->showij();
}
};
int main()
{
derived d;
d.show();
return 0;
}

Please tell me why virtual function is not working in the following code

When i run this code , Output is as expected "This is derived 2" due to late binding because we used virtual function at the base class.
#include <iostream>
using namespace std;
class Base {
public :
virtual void show() {
cout<<"This is base class"<<endl;
}
};
class Derived : public Base {
public:
void show() {
cout<<"This is derived class"<<endl;
}
};
class D2 : public Derived {
public :
void show () {
cout<<"This is derived 2"<<endl;
}
};
int main() {
Base *obj = new D2();
obj->show();
return 0;
}
Similarly, if i change the code to
#include <iostream>
using namespace std;
class Base {
public :
void show() {
cout<<"This is base class"<<endl;
}
};
class Derived : public Base {
public:
virtual void show() {
cout<<"This is derived class"<<endl;
}
};
class D2 : public Derived {
public :
void show () {
cout<<"This is derived 2"<<endl;
}
};
int main() {
// your code goes here
Derived *obj = new D2();
obj->show();
return 0;
}
Same thing happens, virtual function is defined in the base class which in this case is "Derived" class and Pointer is also of the type "Derived" so again calling show() gives me the most derived version.
But i can't understand what is happening when virtual function is defined in the "Derived" class and i use the base pointer of the class "Base". The output of the following code
#include <iostream>
using namespace std;
class Base {
public :
void show() {
cout<<"This is base class"<<endl;
}
};
class Derived : public Base {
public:
virtual void show() {
cout<<"This is derived class"<<endl;
}
};
class D2 : public Derived {
public :
void show () {
cout<<"This is derived 2"<<endl;
}
};
int main() {
// your code goes here
Base *obj = new D2();
obj->show();
return 0;
}
Output : "This is base class". Please help me understand this output.
The reason your last snippet does not work is that the void show() function is virtual in your derived class only, but not in the base class. If any of the classes derived from Derived would override it, and then you call it through a pointer to Derived, you would see polymorphic behavior. The way you did it, however, the call through the base pointer is non-virtual, hence it is dispatched to the Base's implementation.
You can fix this by declaring show virtual in the base class:
class Base {
public :
virtual void show() {
// ^^^^^^^
cout<<"This is base class"<<endl;
}
};
Demo 1
or by accessing D2 through a pointer to Derived:
Derived *obj = new D2();
obj->show();
Demo 2
In your final example, D2 is a Base*, so whether or not that class gets derived doesn't matter.
If you had made obj a pointer to Derived or D2, the results would be different.
The static type of object obj is Base *
Base *obj = new D2();
So the compiler can call only member functions declared in this class. In class Base function show is not virtual. So it was selected by the compiler at compilation time. Base class knows nothing about virtual functions declared in derived classses. In your example the base class even does not have a table of addresses of virtual functions because neither function in the class declared as virtual.
That a virtual function of a derived class would be called the derived class shall to substitute the address of the base class virtual function for the address of its own function in the table of addresses of virtual functions in the base class.

Compilation error when base and derived classes defined in separate namespaces

I have defined base class and derived class in separate namepsaces(This is a requirement as several classes can be derived from a single base class and based on behaviour of derived classes they are to be place din separate namespaces.)
Base.h
namespace global
{
{
class Base
{
public:
Base();
virtual ~Base();
virtual int someFunc(int arg1);
}
}
Derived.h
namespace global
{
namespace derived
{
class Derived: public Base()
{
public:
Derived();
~Derived();
}
}
}
Derived.cpp
namespace global
{
namespace derived
{
Derived::Derived() {}
Derived::~Derived() {}
int Derived::someFunc(int arg1)
{
//some code here
}
}
}
When I try to compile this code, I get the error:
no 'int global::derived::Derived::someFunc(int arg1)' member function declared in class global::derived::Derived.
So, do I need to declare someFunc in Derived again?
like:
namespace global
{
namespace derived
{
class Derived: public Base()
{
public:
Derived();
~Derived();
int someFunc(arg1 int);
}
}
}
Now, if there is some Function in a totally separate namespace, that accepts base class reference, how can I pass it derived class reference?
tryFunc(Base &b);
Derived d;
tryFunc(d);
Is this correct?
Thanks.
You basically figured out everything already, you got to declare someFunc in the class body of the derived class.
Also the way of passing to tryFunc(Base &b)is correct