Private inheritance usage from client - c++

I had a question related to private inheritance in C++.
My question is based on a reference related to this page here.
(Under the heading "But What If We Do Need To Inherit?")
The case is point is I declare a base class with a public virtual function. Then I inherit base class under private inheritance and name it derived class. this is shown as below
class base {
public:
base() {}
virtual ~base() {}
virtual void func_1() {
cout<<"base func1"<<endl;
}
void func_t() {
cout<<"base funct"<<endl;
func_3();
}
private:
void func_3() {
cout<<"base func3"<<endl;
func_1();
}
};
class derived: private base {
public:
derived() {}
~derived() {}
virtual void func_1() {
cout<<"derived func1"<<endl;
}
};
base* b = new derived;
b->func_t();
The above statements give error that base is an inaccessible base of derived.
What do I do if I want to call the func_1 as part of above function call function of the derived?

private indicates that names and members are not accessible from outside. The conversation to a private base class is one occourrence. You can simply wrap this conversation into a member function to let it work:
class derived
: private base {
public:
// other stuff
base* get_base() {
return this;
}
};
derived* d = new derived;
base* b = d->get_base();
b->func_t();

Since you inherit base as a private base class, this means that all public members of base (including base::func_1) will be private in derived. The compiler will complain when you declare derived::func_1 as public.
If you need derived::func_1 as public, then you should inherit base publicly. If you do not need it to be public, then you should declare derived::func_1 as being private.

Related

How to hide private base class members and methods from users

Maybe I didn't make my question clear, the following answers are not answering my question. Let me make the question more specific. My question is that I have a base class to send to clients so that clients can develop derived classes at their ends. How can I hide the private methods and members?
For example, in the following code snippets, the base.h file declares the base class which provides three private virtual methods for clients to override in the derived classes. The clients can override none, any, or all of them. Assuming a client developed a derived class called "Derived", and passed the "Derived" class creator to me so that I can create the Derived class somewhere, e.g. Base* p_base = new Derived() and call p_base->Execute() to actually call client implementations of virtual functions DoInitialize(), DoExecute(), DoCleanUp().
BTW: I don't think opaque pointers will work.
In Base.h file:
class Base {
public:
Base();
~Base();
void Execute();
private:
// virtual functions to be overridden by derived classes.
virtual void DoInitialize() {}
virtual void DoExecute() {}
virtual void DoCleanUp() {}
private:
// private members and functions that are intended to hide from clients
std::vector<float> data_;
....
}
In Base.cpp file
Base::Execute() {
DoInitialize();
DoExecute();
DoCleanUp();
}
In clients end
class Derived : public Base {
public:
Derived();
~Derived();
private:
// overide base class methods
void DoInitialize() {}
void DoExecute() {}
void DoCleanUp() {}
}
In my end somewhere:
void main() {
Base* p = DerivedCreater(); // creater a Derived class, assumes DerivedCreater() has passed in by clients.
p->Execute(); // I want to call the client implementation of DoInitialize(), DoExecute(), and DoCleanUp()
}
The way to go is to have an opaque pointer to the implementation.
class BaseImpl;
class Base {
public:
Base();
~Base();
private:
// virtual functions to be overridden by derived classes.
virtual void Initialize() {}
private:
// private members and functions that are not intended to override by derived classes
void Configure() { m_impl->Configure(); }
BaseImpl* m_impl;
}
Then, in the BaseImpl, you keep a pointer to the Base and you call the virtual functions as wanted. You keep BaseImpl.h in your private includes and you don't distribute it to the library users.
See:
https://en.cppreference.com/w/cpp/language/pimpl

The constructor function in a pure virtual class should be "protected" or "public"?

The following example is from the book "Inside C++ object model"
class Abstract_base {
public:
virtual ~Abstract_base () = 0;
virtual void interface () const = 0;
virtual const char* mumble () const
{
return _mumble;
}
protected:
char *_mumble;
};
The author says if I want to initialize _mumble, the data member of the pure virtual base class, a "protected constructor" should be implemented.
But why protected? And why "public constructor" is not suitable for this class?
Thanks for your answers, and it would be perfect if there's an example.
It doesn't really matter, since you're not allowed to construct objects of the base class anyway. Making it protected serves only as a reminder of the fact that the class is supposed to be a base class; it's only cosmetics/documentation.
Consider
struct Base {
virtual ~Base() = 0;
protected:
Base() { std::puts("Base constructor"); }
};
Base::~Base() { std::puts("Base destructor"); }
struct Derived : Base {};
int main()
{
//Base b; // compiler error
Derived d;
Base *b = new Derived();
delete b;
}
Removing the protected doesn't change the meaning of the program in any way.
Abstract classes and construction of such
It doesn't matter if the constructor is public or protected, since an abstract class cannot be instantiated.
You must inherit from it in order to have it's constructor called, and since the Derived class calls the constructor of the abstract class it doesn't matter what protection level you choose, as long as the Derived class can access it.
One reason that one could possibly have for making it protected is to serve as a reminder that the class must be constructed through inheritance, but honestly that should be clear enough when seeing that it has pure virtual member-functions.
example snippet
struct B {
virtual void func () = 0;
virtual ~B () = 0 { };
};
B::~B () { }
struct D : B {
void func () override;
};
int main () {
B b; // will error, no matter if Bs ctor is 'public' or 'protected'
// due to pure virtual member-function
D d; // legal, D has overriden `void B::func ()`
}
A pure virtual class cannot be instantiated, so it doesn't make a difference if the constructor is public or protected.
A public constructor is syntactically correct. However, making it protected will carry a stronger indication that the class cannot be instantiated.
For an example: http://ideone.com/L66Prq
#include <iostream>
using namespace std;
class PublicAbstract {
public:
PublicAbstract() { }
virtual void doThings() =0;
};
class ProtectedAbstract {
protected:
ProtectedAbstract() { }
public:
virtual void doMoreThings() =0;
};
class B: public PublicAbstract {
public:
void doThings() { }
};
class C: public ProtectedAbstract {
public:
void doMoreThings() { }
};
int main() {
B b;
C c;
return 0;
}
A public constructor would not be very useful, since abstract classes cannot be instantiated in the first place.
A protected constructor makes sense: this way, a derived concrete class can provide its own public constructor that chains to the protected constructor of the base abstract class.
Protecetd ctor will make sure the ctor gets called by only the classes which derive from Abstract_base.
Public ctor is not suitable because the class contains a pure virtual method! How are you planning to instantiate a pure-virtual class if not via its child classes?

How to make a derived class access the private member data?

I'm stuck with a c++ problem. I have a base class that has a self referential object pointer inside the private visibility region of the class. I have a constructor in the base class that initializes these two pointers. Now I have my derived class whose access specifier is private(I want to make the public member functions of my base class private). Now through the member functions of my derived class I want to create an object pointer which can point to the private data of the base class, that is ,those self referential object pointers. My code is:
class base{
private:
base *ptr1;
int data;
public:
base(){}
base(int d) { data=d }
};
class derived:private base{
public:
void member()
};
void derived::member()
{
base *temp=new base(val); //val is some integer
temp->ptr1=NULL; //I can't make this happen. To do this I had to declare all the
//private members of the base class public.
}
Derived class can not access the private members of it's base class. No type of inheritance allows access to private members.
However if you use friend declaration you can do that.
There is no other way to access other class's private data then friendship. What you can do with inheritance, however, is to access protected data of the base class. But it doesn't mean you can access protected data of another object of the base type. You can only access protected data of the base part of the derived class:
class base{
protected: //protected instead of private
base *ptr1;
int data;
public:
base(){}
base(int d) { data=d; }
};
class derived:private base{
public:
void member();
};
void derived::member()
{
base *temp=new base(3);
//temp->ptr1 = 0; //you need friendship to access ptr1 in temp
this->ptr1 = 0; // but you can access base::ptr1 while it is protected
}
int main(){}
try to give protected as the access specifier in base class and inherit the base class in private mode.....but for further using member functions of base class u may need few short inline functions as they will also be converted to private
Well I think, you were trying to achieve a result like this!! This does not report any compiler error or such. Good luck!!!
class base{
private:
base *ptr1;
int data;
public:
base(){}
base(int d) { data=d; }
base* getPtr(); //getter to get access to base pointer
void setPtr(base* val); // setter to set value of the pointer variable
};
base* base::getPtr()
{
return ptr1;
}
void base::setPtr(base* val)
{
ptr1 = val;
}
class derived:private base{
private:
base* getPtr();
void setPtr(base* val);
public:
void member();
};
base* derived::getPtr()
{
return base::getPtr(); //derived version just invokes the base class version
}
void derived::setPtr(base* val)
{
base::setPtr(val); //derived version just invokes the base class version
}
void derived::member()
{
base *temp=new base(5); //put in a random number here instead of val
temp -> setPtr(nullptr);
}
I disagree with some of the other answers claiming the only way to access the private member is by making it a friend.
You can directly access the private member via its address in memory. If you're comfortable with it that is. You could have a function in the base class that returns the address of the private member and then use some wrapping function in the derived class to retrieve, dereference and set the private member.

virtual inheritance query

class Base {
public:
Base(){ }
virtual void Bfun1();
virtual void Bfun2();
};
class Derv : public Base {
public:
Derv(){ }
void Dfun1();
};
Is there a difference between above definitions and the below ones ? Are they same ? if not how both are the different functionally ?
class Base {
public:
Base(){ }
void Bfun1();
void Bfun2();
};
class Derv : public virtual Base {
public:
Derv(){ }
void Dfun1();
};
They are completely different. The first set defines Bfun1 and Bfun2 as virtual function, that allows overriding them in the derived class and call those in the derived class through a base class pointer:
// assume you've overridden the functions in Derived
Base* base_ptr = new Derived;
base_ptr->Bfun1(); // will call function in derived
The second set, however, they're just normal functions. Instead, you declared the base class to be virtual, which has many implications you best read about in a good C++ book or search through the SO questions, I think we have one on that topic.

How do you make a private member in the base class become a public member in the child class?

Consider the following code:
class Base
{
void f() { }
};
class Derived: public Base
{
public:
};
What can you change in the derived class, such that you can perform the following:
Derived d;
d.f();
If the member is declared as public in the base class, adding a using declaration for Base::f in the derived class public section would've fix the problem. But if it is declared as private in the base class, this doesn't seem to work.
This is not possible. A using declaration can't name a private base class member. Not even if there are other overloaded functions with the same name that aren't private.
The only way could be to make the derived class a friend:
class Derived;
class Base
{
void f() { }
friend class Derived;
};
class Derived: public Base
{
public:
using Base::f;
};
Since you make the names public in the derived class anyway so derived classes of Derived will be able to access them, you could make them protected in the base-class too and omit the friend declaration.
You cannot access a private member from the derived class. What you can do is make it protected, and use a using declaration:
class Base
{
protected:
void f() { }
};
class Derived: public Base
{
public:
using Base::f;
};