‘base’ is an inaccessible base of ‘deriv’ - c++

Why is base inaccessible to deriv inside deriv? The program compiles with class deriv : public base.
#include <cstdio>
class base
{
};
class deriv : base
{
public:
void f(deriv, int){printf("deriv::f(deriv, int)\n");}
void f(base){printf("deriv::f(base)\n");}
};
int main()
{
deriv d;
d.f(d);
}
17: error: ‘base’ is an inaccessible base of ‘deriv’
17: error: initializing argument 1 of ‘void deriv::f(base)’
Because two people got it wrong already, I will ask in bold: why does base need to be publicly inherited? It is accessed from within deriv only.

You seem to be incorrectly assuming that conversion from deriv to base when calling deriv::f(base) occurs "inside deriv" and thus has to be accessible. This is not the case. When you call a function, all conversions necessary for initializing function's arguments occur in the caller's context. They are not "inside derive". They happen in the "outside world". And in your case the "outside world" has no access to deriv-to-base conversion.
In your specific case it is main that is trying to convert deriv to base. And main cannot do it since it has no access to the private base of deriv. Just to experiment you can declare int main() as a friend of deriv and the code will compile.

If you define a class with the class keyword, then members and base classes are private by default.
If the base class needs to be public, then either explicitly declare it public (as you mention in the question), or use the struct keyword which makes things public by default.
why does base need to be public?
In this case, your call to f(base) requires a conversion from deriv to base, and such a conversion is only possible if the base class is accessible. Being private, it is not accessible in main, which is where the conversion is required.

Because it is privately inherited :
class deriv : base
The default inheritance for class is private, meaning other classes and functions do not have access to the base class of the derived class.
There is a small problem in your example. This :
deriv d;
d.f(d);
is not going to do what you expect it to do because of slicing.
If we fix the above problem by changing the signature of the f to this :
void f(base&){printf("deriv::f(base)\n");}
there is still a problem accessing the base class of deriv, because it inherited privately from the base.

Related

Does public static functions of base class become member functions of derived class if base class is inherited publicly?

I am trying to run the following code but getting error.
#include <iostream>
template <typename T>
class Base {
public :
static T& Get() {
static T t;
return t;
}
};
class Derived : public Base<Derived> {
private :
Derived() {}
// friend Base<Derived>; //un-commenting this will make code work.
};
int main() {
Derived& d = Derived::Get();
return 0;
}
Error :
prog.cpp: In instantiation of ‘static T& Base::Get() [with T = Derived]’:
prog.cpp:18:24: required from here
prog.cpp:7:14: error: ‘Derived::Derived()’ is private within this context
static T t;
^
prog.cpp:14:4: note: declared private here
Derived() {}
^~~~~~~
I have following questions
class Derived is publically derived from class Base, doesn't it makes Get() a member function of Derived too ?
If [1] is true, and Get() becomes a member function of Derived, then
why it's not able to call the private constructor of Derived.
Assume we have multiple classes to be implemented as Singleton, is
there a way we can do it using templates with something similar to
the above example? (additional question)
I understand :
We can make the above code work by making base a friend of derived
line to the code.
We can make Get() as "non static virtual function" and override in
the derived classes.
I am not looking for the above mentioned solutions. Though, please let me know if this(these) is(are) the only possible solutions to achieve this kind of design.
class Derived is publically derived from class Base, doesn't it makes Get() a member function of Derived too ?
Yes in the sense that the lookup Derived::Get() will work, but it call the very same function as if you wrote Base<Derived>::Get().
If [1] is true, and Get() becomes a member function of Derived, then why it's not able to call the private constructor of Derived.
Because different classes cannot access private members by name. This is what private is for. The same reason why Derived cannot access private members of Base.
Assume we have multiple classes to be implemented as Singleton, is there a way we can do it using templates with something similar to the above example? (additional question)
Isn't that what your example is doing?
We can make the above code work by making base a friend of derived line to the code.
Correct.
We can make Get() as "non static virtual function" and override in the derived classes.
I don't think so. You cannot call that virtual function without an object. You'd be required to create an instance of Derived before calling Get, but Get is supposed to create our object.
Though, please let me know if this(these) is(are) the only possible solutions to achieve this kind of design.
I would probably go forthe friending. Simple, concise and does what you want. There is other solutions like having a protected type in the base, and defining a public constructor that receive that protected type, but this is quite leaky and I won't recommend.
class Derived is publically derived from class Base, doesn't it makes Get() a member function of Derived too ?
No. Member functions (static and non-static) of base are member functions of base, not member functions of the derived class. However, the member functions of base(s) are looked up when invoking a member function (depending on visibility).

Instantiating Derived class which inherits privately or protectedly from Base

I have the following hypothetical code:
class Base {
public:
virtual void print() {
std::cout << "Base\n";
}
// assume virtual destructor
};
class Derived : private Base {
public:
void print() {
std::cout << "Derived\n";
}
};
int main() {
// Derived d{}; works fine
Base *pd = new Derived{}; // doesn't work
pd->print();
// assume memory is deallocated
}
At first, I thought that it would work, because constructors aren't inherited anyways. But the compiler gives the error:
error: 'Base' is an inaccessible base of 'Derived'
And I'm not able to figure out what is really happening?
It's a good guess, but the problem isn't with constructors or member functions.
In the line
Base *pd = new Derived{}; // doesn't work
The compiler is implicitly converting the right side, new Derived{}, which is of type Derived*, to the type Base*.
The term that the standard uses to describe when one can implicitly convert a pointer to a derived class to a pointer to a base class is accessibility. From subsection 11.2/5:
If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base class
There are a few technical conditions listed (11.2/4 if you really care) that can make a base class accessible, but Base meets none of these.
The short version is, private inheritance hides the base class and the access specifier private needs to be public for your code to compile. Hope that helps.
You are deriving Base privately, and that's why you are getting error.
With private inheritance, all members from the base class are inherited as private. This means private members stay private, and protected and public members become private. Thats why you are not able to use print()in main Compiler is not able to cast derived pointer to base type, because the inheritance is private.
In a context where the knowledge of the internals of the derived class is hidden (IE non-friend, not in a class derived from Derived) it seems like there is no relationship between the two classes.
When you try to assign to a pointer of the base type you are saying convert this Derived pointer to a Base pointer. As the inheritance is hidden, it is like you are trying to assign it to a pointer of an unrelated type. However the compiler does know that it is related, so rather than just giving you a unhelpful error, it tells you that the conversion that you are trying to do is inaccessible.

Calling private function by upcasting [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++: overriding public\private inheritance
class base {
public:
virtual void doSomething() = 0;
};
class derived : public base {
private: // <-- Note this is private
virtual void doSomething()
{ cout << "Derived fn" << endl; }
};
Now if I do the following:
base *b = new derived;
b->doSomething(); // Calls the derived class function even though that is private
Question:
It's able to call the derived class function even though it is private. How is this possible?
Now if I change the inheritance access specifier from public to protected/private, I get a compilation error:
'type cast' : conversion from 'derived *' to 'base *' exists, but is inaccessible
Note: I am aware of the concepts of the inheritance access specifiers. So in the second case as it's derived private/protected, it's inaccessible. But I wonder about the answer to first question. Any input will be highly appreciated.
Access control is implemented at compile time, not run-time, while polymorphism (including the use of virtual functions) is a run-time feature.
In the first case the access check is done (as it is always done) on the static type that the call is made through. The static type of *b is base, and in that case doSomething() is public.
C++03 11.6 "Access to virtual functions" says:
The access rules (clause 11) for a virtual function are determined by
its declaration and are not affected by the rules for a function that
later overrides it. [Example:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); //OK:B::f()is public,
// D::f() is invoked
pd->f(); //error:D::f()is private
}
—end example]
Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.
Keep in mind especially that "the access of the member function in the class in which it was defined (D in the example above) is in general not known". In general, at the point in your example where b->doSomething(); is called, the compiler may have no knowledge at all about derived (or child), much less whether or not the access to derived::doSomething() is private.
Private functions are meant to be hidden from the outside world and from the derived classes. Although you are overriding the access specifier of the parent's DoSomething and making it private, you are instantiating a base class; so in the first case, you can call base's DoSomething as it is public. This scenario can be used if you want to stop people deriving from your derived class.
In the second case, the private access specifier causes the base's members not to be exposed to the users of the derived class, which effectively makes the derived class useless.

Private virtual function in derived class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++: overriding public\private inheritance
class base {
public:
virtual void doSomething() = 0;
};
class derived : public base {
private: // <-- Note this is private
virtual void doSomething()
{ cout << "Derived fn" << endl; }
};
Now if I do the following:
base *b = new derived;
b->doSomething(); // Calls the derived class function even though that is private
Question:
It's able to call the derived class function even though it is private. How is this possible?
Now if I change the inheritance access specifier from public to protected/private, I get a compilation error:
'type cast' : conversion from 'derived *' to 'base *' exists, but is inaccessible
Note: I am aware of the concepts of the inheritance access specifiers. So in the second case as it's derived private/protected, it's inaccessible. But I wonder about the answer to first question. Any input will be highly appreciated.
Access control is implemented at compile time, not run-time, while polymorphism (including the use of virtual functions) is a run-time feature.
In the first case the access check is done (as it is always done) on the static type that the call is made through. The static type of *b is base, and in that case doSomething() is public.
C++03 11.6 "Access to virtual functions" says:
The access rules (clause 11) for a virtual function are determined by
its declaration and are not affected by the rules for a function that
later overrides it. [Example:
class B {
public:
virtual int f();
};
class D : public B {
private:
int f();
};
void f()
{
D d;
B* pb = &d;
D* pd = &d;
pb->f(); //OK:B::f()is public,
// D::f() is invoked
pd->f(); //error:D::f()is private
}
—end example]
Access is checked at the call point using the type of the expression used to denote the object for which the member function is called (B* in the example above). The access of the member function in the class in which it was defined (D in the example above) is in general not known.
Keep in mind especially that "the access of the member function in the class in which it was defined (D in the example above) is in general not known". In general, at the point in your example where b->doSomething(); is called, the compiler may have no knowledge at all about derived (or child), much less whether or not the access to derived::doSomething() is private.
Private functions are meant to be hidden from the outside world and from the derived classes. Although you are overriding the access specifier of the parent's DoSomething and making it private, you are instantiating a base class; so in the first case, you can call base's DoSomething as it is public. This scenario can be used if you want to stop people deriving from your derived class.
In the second case, the private access specifier causes the base's members not to be exposed to the users of the derived class, which effectively makes the derived class useless.

Private Inheritance and Derived Object to Base reference

As far as I understand the reason that we cannot pass a derived class object to a base class reference for private inheritance is that Since Derived is privately inherited from Base, the default constructor of Base would be called before the constructor of Derived. But because it is private and not inherited to Derived, we get a compiler error.
But, if I try to create a public constructor for Base and inherit from Derived privately and then re-assign the public status to Base's constructor will it allow me to pass a derived's instance to Base reference?
I tried it as follows,
#include <iostream>
using namespace std;
class base
{
public:
base(){}
void print(){ puts("In base"); }
};
class derived : private base
{
public:
base::base; /* Throws an error - Declaration doesnt declare anything*/
void print(){ puts("In derived"); }
};
void func(base& bRef)
{
}
int main()
{
derived dObj;
func(dObj); /* Throws an error - 'base' is an inaccessible base of derived */
}
It throws an error for base::base (publicizing privately inherited constructor to public).
Is what I am trying valid? Can anyone please tell me?
The reason we cannot have a base class reference to a derived object that inherits privately is because that would violate the Liskov Substitution Principle: the derived object IS-NOT-A base class object because it does not provide the base class public interface. You cannot work around this
For this reason, private inheritance is a way of reusing implementation and not when you want to make a more specialized type. As this can most of the time be done with composition (i.e. having a member of the base class instead of privately deriving), private inheritance might be a bad code smell.
You can read here (be sure to follow all the links) for more information on when private inheritance is a good option (summary: when there simply is no other choice).
No, it is not valid to point to an object of Derived with a pointer or reference of Base class. If it were possible, then the whole purpose of private inheritance (hide the fact that the derived class inherits part (or the whole) of its functionality from the base class) would be useless.
Say you have a method foo() in the base class. You don't want this method to be called. But if it were possible to point the object from a pointer of the base class, then it would also be possible to call foo().
Base * ptrBase = &objDerived; // Let's suppose this would compile
ptrBase->foo(); // Now we can call foo() (?)
When you declare private inheritance, is as if the Derived class where not related to the base class. It is just you, the developer, the only one that should "know" that this relationship exist, and actually you should forget about it, because it just won't work.
Private inheritance is just there solely as a reusability mechanism, not as a true inheritance mechanism. It is not recommended to even use it, since you can obtain a better result by simply applying composition (i.e. just make an attribute of class Base in Derived).