How to skip a class with public access to a function? - c++

I have this setup:
class A
{
public:
virtual void Function();
}
class B : private A
{
}
class C : public B
{
public:
// I want to expose A::Function() here
}
I tried to do this by adding:
class C : public B
{
public:
virtual void Function();
}
and
C::Function()
{
A::Function();
}
but I get and "inaccessible base" error.
Is it possible to do something like this?

In B you can change the accessibility of A::Function to protected:
class B : private A
{
protected:
using A::Function;
};
In C::Function (and elsewhere in C) you will then have to refer to the function as B::Function, not A::Function. You could also public: using B::Function; in C instead of implementing a C::Function that just calls B::Function.

You can't do this. The fact that B inherits from A is an implementation detail and you are not allowed to access it from C- just like you can't access B's private functions or member variables.
This would be completely legal if B inherited protected or public from A.

If you can change it to class B : protected A it should work.

Not really. The scenario you're describing would indicate that your class hierarchy needs to be reworked.

Related

C++ Multilevel Inheritance, Polymorphism

Suppose i have three classes A, B and C. class B inherits from class A and the inheritance is private whereas class C inherits from B and the inheritance is public. Now class A has a protected function which class C wants to access. So, what must be done in class B to make that protected function available to class C.
Here is the link to the code : http://pastebin.com/9E2sLZzj
The "using" keyword makes a member of an inherited class visible, and resolvable, in the scope of its subclass. So, to make the privately-inherited member available to B's subclasses:
class A {
protected:
void foo() {}
};
class B : private A {
protected:
using A::foo;
};
class C : public B {
void bar()
{
foo();
}
};
Okay i got the solution
This code fragment worked after inserting it into Class B.
int get(){
return A::get();
}
Not sure what it does though

C++ Extending Class Forcing some methods private

My question is simple: ~Given two classes, I want to one of them to extend the other one, but turning some methods to be private:
Class B
public Method a();
public Method b();
public Method c();
Class A extends B
private Method a();
private Method b();
public Method c();
Is this possible and how?
Thanks!
This is what Private Inheritance is for.
class A: private B
{
// All methods of class B are now private.
// To make some "public" again:
public:
Method c() { return B::c(); } // Call the private c-method from class B.
};
Use private inheritance, all the function in base class B will become private.
class A: private B
{
}
Difference between private, public, and protected inheritance in C++ are explained here.
You could change the inheritance type from public to private, when you declare class B.
class B : public A {
private:
baseMethod();
};
or
class B : private A {
public:
baseMethod();
};
The use appropriate override that you want for each method.
Looks like you don't want all of the methods to turn private. Choose the type of inheritance based on the fraction of methods changing their visibility.

You can 'promote' access specification through inheritance, can you ever 'demote' access specification?

By 'promote' I mean make access more restrictive and by 'demote' I mean make less restrictive.
For example, when class B is derived from class A using : protected or : private then the public members of A get promoted, to protected and private, respectively.
Could some class C ever come in and derive itself from class B, while at the same time demoting the inherited members of class A back to their original access specifications?
If you're using protected derivation, then class C could indeed give access to the protected members, by creating an appropriate wrapper:
class A {
public:
void F();
};
class B : protected A { };
class C : public B {
public:
using B::F;
};
This also can be made to work with data members:
class A {
public:
int n;
};
class B : protected A { };
class C : public B {
public:
using B::n;
C() : n(this->B::n) { }
};
With private inheritance this is not directly possible, because C cannot itself access members in A.. However, if B is derived from A using private virtual inheritance, it becomes possible again:
class A {
public:
void F();
};
class B : private virtual A { };
class C : public B, public virtual A { };
int main() {
C x;
x.F();
return 0;
}
This works because with virtual inheritance, C can derive directly from the same instance of A as B, but with a different access specifier.
A using declaration can give access to public or protected members of protected base classes:
struct A {int x;};
struct B : protected A {};
struct C : B
{
using A::x; // publicly accessible
}
Obviously, private members and base classes aren't available to C, so you can't reduce the restrictions on them.
Of course not, what would be the point of having private or protected inheritance if I can just create another derived that class that blows away the intermediate class' access restrictions and makes everything public?
No.
Because, when class C derives class B; it doesn't know about the original access specifiers of class A. It just respects the access specifiers in class B.

Refer base class members from derived class

class A {
public:
void fa() {
}
};
class B : public A{
public:
void fb() {
}
};
class C : public A, public B {
public:
void fc() {
//call A::fa(), not B::A::fa();
}
};
How to call A::fa() from C::fc() function.
GCC warns withdirect base A inaccessible in C due to ambiguity, does this mean there is no direct way to refer base class members?
One option would be to create a stub class that you can use for casting to the right base class subobject:
struct A {
void fa() { }
};
struct B : A {
void fb() { }
};
// Use a stub class that we can cast through:
struct A_ : A { };
struct C : A_, B {
void fc() {
implicit_cast<A_&>(*this).fa();
}
};
Where implicit_cast is defined as:
template <typename T> struct identity { typedef T type; }
template <typename T>
T implicit_cast(typename identity<T>::type& x) { return x; }
I just found the following info from ISO C++ 2003 standard (10.1.3)
A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be
an indirect base class more than once and can be a direct and an indirect base class. There are limited
things that can be done with such a class. The non-static data members and member functions of the direct
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations
and types can be unambiguously referred to.
It means there is no direct way :(
I just compiled you code on codepad.org , putting A::fa() is enough to call fa() from your C::fc() function.
void fc() {
A::fa();
}
The below is the link to codepad with your code.
http://codepad.org/NMFTFRnt
I don't think you can do what you want. There is an ambiguity here: when you say A::fa(), it still doesn't tell the compiler which A object to use. There isn't any way to access class A. That's what the warning is telling you.
This seems like an awfully strange construct, though. Public inheritance should be used for is-a relationships. You are saying that C is-a A twice over? It doesn't make sense. And that suggests that this is either an artificial example that would never come up in practice, or you should reconsider this design.
You can use virtual inheritance to overcome such problem:
class B : virtual public A {
Now, you can use A::fa() simply in the child class C.
void fc()
{
fa();
}
However, I generally don't see any practical need to inherit class A again into class C, when B is already publically inheriting A. So, In your case, you can make it simple:
class C : public B {
Edit:
If you want 2 instances for A. then the direct instance which you are intending can be made as an object of C:
class C : public B {
A obj;
Because, having a directly inherited A will not be usable in anyway. You cannot declare any pointer or reference to it inside the scope of C.

Inheriting both abstract class and class implementation in C++

I hope this is a simple question.
Can I inherit both an abstract class and it's implementation? That is, can the following be made to work?
class A {
virtual void func1() = 0;
}
class B {
void func1() { /* implementation here */ }
}
class C : public A, public B {
}
I've tried a few variations, and am getting compile errors complaining about unimplemented methods in class C. I can save a lot of repeated code if I can make this work, however. Is it possible?
I solved this by creating a "composite class" called D which inherits from A & B, but contains the implementation code previously contained in B. This makes my inheritance model less clean, but it solves the problem without requiring code duplication. And, as I noted in the comments below, it makes my naming conventions pretty gross.
class A {
virtual void func1() = 0;
}
class B {
// Other stuff
}
class D : public A, public B {
void func1() { /* implementation here */ }
}
class C : public D {
}
class B is not an implementation of class A in your code. Class B should be inherited from class A and func1 should be virtual. Only in that case class B will be implementation of class A. And then there is no need to inherit from both A and B.
class A {
virtual void func1() = 0;
}
class B : public A {
virtual void func1() { /* implementation is here */ }
}
class C : public B {
}
Otherwise you will get unimplemented pure virtual function func1.
Make B inherit from A. If that is not possible, using virtual inheritance might also work (I am not entirely sure about this).
If you want to reuse code from B class in C class, try to do something like this:
class C : public A, public B {
void func1(){ B::func1(); }
}
As Kirill pointed out: Your premise is wrong.
Class B in your example does not inherit class A (it needs to be declared to do that first).
Thus, B.func1() is something entirely different to A.func1() for the compiler. In class C it is expecting you to provide an implementation of A.func1()
Somebody above posted something along the lines of:
class C : public A, public B
{
// implement A::func1()
virtual void func1()
{
// delegate to inherited func1() in class B
B::func1();
}
}