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
Related
I have a header file with 2 classes. class A (which is a very big class) and class B that inherits class A. I don't want people to be allowed to create objects of class A or even be able to see its static members. They should only to work with class B. What is the best way of doing that.
(Generally speaking A is a "helper class")
To restrict the creation of the class, make the constructor of class A private and declare class B as a friend class. This way only B can instantiate A.
class B;
class A
{
private:
A();
friend class B;
};
The same applies to methods (static or not): make them all private and the friend statement will allow B to access A's members.
Edit: works with protected as well.
I don't want people to be allowed to create objects of class A
What you are looking for is called an "abstract base class". In C++, any class that has at least one abstract member is automatically an abstract class, there is no additional keyword like in other languages.
class A
{
public:
virtual void Test() = 0; // abstract, has no implementation
};
class B : public A
{
public:
virtual void Test() {} // not abstract, has an implementation
};
int main()
{
A a; // this will produce a compiler error.
B b; // this is fine
return 0;
}
or even be able to see its static members
Well, don't make them public. Either make them protected or private and grant friend access to your B class.
Here's what I'm trying to do:
class A
{
friend class C (and all of C's derived classes)
public:
void DoAThing() { mpMyC->DelegateResponsibility(myB); }
private:
class B
{
};
B mMyB;
C* mpMyC;
};
class C
{
// No problem here- C can see B
virtual void DelegateResponsibility(const A::B& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const A::B& necessaryInfo);
};
In short, I have a private nested class inside A because it's an implementation detail of A. However, I'd like to delegate some responsibilities of A to C and C's derived classes to get some polymorphic behavior. I'd like to avoid having to add a friend class line every time someone derives from C. The standard workaround given for derived friend classes is "just add a protected accessor function to your base class and override it for derived members" but that only helps access private members of class A, not privately scoped classes. Is there any way to workaround this issue?
This should work:
class C
{
typedef A::B MyB;
virtual void DelegateResponsibility(const MyB& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const MyB& necessaryInfo);
};
You could put your class B in a detail namespace, at file scope.
something like this:
namespace my_hidden_area {
class B {
...
}
}
It's not as strong protection as making the class nested private, of course, but it should make it clear to outsiders that they should not be messing around with B.
If you're wondering why friendship is not inheritable, see this question: Why does C++ not allow inherited friendship?
Say we have a class inheriting from two base classes (multiple inheritance). Base class A is abstract, declaring a pure virtual function foo, the other base class B declares and implements a function foo of the very same signature.
struct A
{
virtual void foo(int i) = 0;
};
struct B
{
virtual void foo(int i) {}
};
struct C : public A, public B {};
I want to use the implementation of foo from base class B in my derived class C. However, if I do not implement the function foo a second time in my derived class C, I cannot instantiate any object of it (it remains abstract). Virtual inheritance does not help here as expected (class A and class B have no common base class).
I wonder if there is a way to "import" the implementation of foo from class B into class C in order not to have to repeat the same code.
Above example is of course contrived. The reason I want implement foo in class B is that I want to derive class D : public B and use class Bs implementation of foo. I know that inheritance is not (primarily) intended for code reuse, but I'd still like to use it in that way.
In java, your sample code works. In C++ it doesn't. A subtle difference between those languages.
Your best option in C++ is to define C::foo() by forwarding to B::foo():
struct C : public A, public B
{
virtual void foo(int i) { B::foo(i); }
};
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.
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.