Problem in virtual inheritance - c++

class base {
protected:
base() {}
};
class der1 : virtual private base {
public:
der1() {}
};
class der2 : public der1
{
public:
der2() {}
};
int main() {
der2 d;
}
It gives compile time error: 'base::base' : cannot access inaccessible member declared in class 'base'
But base class constructor is define publically it compiles.
Pls anyone can give explaination?

Because base is a virtual base class, it must be initialized by the most derived class in the hierarchy of an object being instantiated. base's contructor may be protected and accessible to classes derived from it, but that doesn't help as base is a private base class of der1 so even classes derived from der1 don't have access to the base parts of "*this".
You need to relax the access restrictions on the base base class to at least protected.

The base class constructor is declared protected, but that is not the problem. The main problem will be the private inheritance in der1. This way, der2 cannot access the constructor of base which it needs in order to construct itself.

Replace virtual private base
with virtual protected base and der2 will be able to access to the constructor of base

Related

Assert private inheritance in C++

I would like to assert that a base class is only inherited private.
class Base {
static_assert(...); //check if its derived privat
};
class PublicDerived : public Base {}; //this should fail
class PrivateDerived : private Base {}; //this should work
Is there a way to achieve this?
Base can also be a template class.
My problem was that I don't want that the destructor is called from this base class. For example from delete Base* or unique_ptr<Base>.
A protected destructor solves this issue.
Now the derived classes can use these functionalities the base class provides.
Public inheritation is still possible, but my use case is fullfilled.
class Base {
//...
protected:
constexpr Base() noexcept = default;
~Base() noexcept = default;
};

C++: Why Protected Constructor Cannot be Accessed in the Derived Class?

Protected member is supposed to be accessible from derived class.
Then, why I got the compiling error in the code below?
class A {
protected:
A() {};
};
class B : public A {
public:
void g() {
A a; // <--- compiling error: "Protected function A::A() is not accessible ...". Why?
}
};
int main() {
B b;
b.g();
}
I noticed there is a related post, but the class there is a template class. Mine is just a "regular" class.
Why the derived class cannot access protected base class members?
protected members could be accessed from derived class, but only when through the derived class.
A protected member of a class is only accessible
...
to the members and friends (until C++17) of any derived class of that class, but only when the class of the object through which the protected member is accessed is that derived class or a derived class of that derived class:
So you can't create an indpendent object of base class even in member functions of derived class.
Put it in another way, the protected members of the current instance of derived class could be accessed, but protected members of independent base class can't. E.g.
class A {
protected:
int x;
public:
A() : x(0) {}
};
class B : public A {
public:
void g() {
this->x = 42; // fine. access protected member through derived class
A a;
a.x = 42; // error. access protected member through base class
}
};
Protected member is supposed to be accessible from derived class.
Yes, but only when accessed via the this pointer. Not when accessed on a complety separate object. Which you are trying to do, when B::g() tries to construct a new A object.

Why can't a friend function access the private variables of an inherited class?

Isn't the friend function supposed to access everything that is in Base class and Derived class? class Derived: public Base -> everything that is in private in Base is now public inside the class derived.
class Base
{
private:
int x;
};
class Derived : public Base
{
int y;
public:
void SetY(int value);
void friend SetX(Derived &d);
};
void SetX(Derived &d)
{
d.x = 100; // Why is this a problem?
// Isn't Base supposed to be public now that is inherited?
}
int main()
{
Derived d;
SetX(d);
}
Your friend function void friend SetX(Derived &d); of Derived class is a friend function of that class only and it can only access private members of Derived class only but not allowed to access any private or protected member of a Base class. Also even from a Derieve class you can not access private members of a Base class but can access only the public and protected members. To reach/access the private members of a Base class you have to use public member function of base class.
There are two types of inheritance in C++
class B{};
class D:public B{};
All I mentioned above is applicable in the above case. Even though you inharite base B class as public to a Derieve class D all the private members inharites to Derieve D as private, protected members as protected and public as public.
But if you inharite as private like below all the members of Base class would be now private to the Derieve class.
class B{};
class D:private B{};
In this case a friend function can not even access any member of Base class B.
Isn't the friend function supposed to access everything that is in Base class and Derived class?
No. It is a friend of Derived, so it is supposed to access everything that the Derived class can access.
class Derived: public Base -> everything that is in private in Base is now public inside the class derived.
No. Everything that was private in Base before, is still private.
The use of public/protected/private for inheritance means something different than it does for member access control.

Private inheritance usage from client

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.

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;
};