Assert private inheritance in C++ - 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;
};

Related

breaking virtual inheritance avoiding explicit base ctor

Following explanation and examples from here I have exemplary constructed the following inheritance model creating a diamond
class Base {
public:
int data_;
Base(int d) : data_(d) {}
Base() = deleted;
};
class A : public virtual Base {
public:
A() : Base(42) {};
};
class B : public virtual Base {
public:
B() : Base(24) {};
}
class AB : public A, public B {
public:
AB() : Base(-1) {};
}
so far so good; note, that AB() needs to call to the Base(int)-ctor now. This is kind of understandable, because having the alternative initializer branches of going through AB>>A>>Base or AB>>B>>Base would not result in a well defined behavior at that.
Lets branch out from class A into a side-branch before we even have closed the diamond:
class A_Child : public A {
public:
A_Child() : A() {}; // not permitted by compiler
}
This will not compile, as the compiler will explicitly ask for to specify the ctor Base(int) in the inializer list of A_Child.
I don't quite understand this behavior; as we are no longer virtually inheriting at this point and the path of initalization of A_Child>>A>>Base is not ambiguous.
It seems now for every furthermore derived class of A_Child I have to again specify the Base(int) initializer explicitly. This is kind of breaking the encapsulation as every code that derives from this class needs to know how the class at the very base acts and is implemented.
Is there any way to stop or to break the virtual inheritance once I branch into a side-line?

Inherit from arbitrary class in c++?

Is it possible to design a class that will inherit from any one of a group of base classes? I would like to be able to write something like:
class Derived : public ArbitraryBase {
public:
Derived () : ArbitraryBase () {}
...
};
where ArbitraryBase can be some base class determined at compile time. I have a group of base classes that I would like to derive identical classes from. Is there a way to avoid writing an individual derived class for each of the base classes?
If it is truly determined at compile time, you can make your derived class a template:
template<class T>
class Derived : public T {
public:
Derived() {}
...
};
You can later create instantiate this class by providing the base type:
int main() {
Derived< ??? > my_object;
...
}
Where ??? is some compile time way of getting your derived type.
You can do this via a template. Using
template<typename T>
class Derived : public T
{
public:
Derived() : T() {}
// or just use if actually need to provide a default constructor
Derived() = default;
};
gives you a class that inherits from T and calls T's default constructor. You would create a concrete class with it like
Derived<Base1> d;
and now d is a Derived that inherits from Base1.
If you need to inherit from an arbitrary number of bases then you can use a variadic template like
template<typename... Bases>
class Derived : public Bases...
{
public:
Dervied() : Bases()... {}
// or just use if actually need to provide a default constructor
Derived() = default;
};
and it would be used like
Derived<Base1, Base2, ..., BaseN> d;

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.

Problem in virtual inheritance

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

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