How to split definition and declaration with friend function and inheritance - c++

I need to compile something like this:
struct Base {
virtual void func1()=0;
// ...
friend void Derived::func2(Base *base);
private:
int some_private;
}
struct Derived : Base {
virtual func3()=0;
// ...
void func2(Base *child) {
std::cout << child->some_private;
}
};
But I keep getting compilation error. I tried swapping structures or declaring them first, but I can't declare Derived first (because of inheritance), and I can't declare Base first (because I need to declare friend function in Derived). What to do?

You have a few basic solutions. The most obvious is to change from private to protected. In C++, protected means subclasses have access.
You can add more public (perhaps protected) accessor methods instead.
You can forward-reference the entire Derived class and friend the entire class.
Personally, I have never felt a need to use friend methods or classes, and I don't know under what circumstances I'd have to be in before I wouldn't depend on other ways to accomplish whatever I'm trying to accomplish.
For this particular solution, I'd change the access to protected.

Related

C++: Creating derived class that has access to private variables of base?

I have an abstract class base with private member variable base_var. I want to create a derived class, which also has base_var as a private member.
To me, this seems like an obvious thing you would want to do. base is abstract so it will never be instantiated. The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
However, the below diagram seems to suggest that this is not doable with inheritance?
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
However, the below diagram seems to suggest that this is not doable with inheritance?
Correct, private members of a class can not be accessed by derived classes. If You want a member of a class to be accessible by its derived classes but not by the outside, then You have to make it protected.
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
Even an abstract class can have member functions which act on a (private) member variable. Consider (somewhat silly example, but well):
class MaxCached
{
private:
int cache = std::numeric_limits<int>::min();
public:
bool put(int value)
{
if (value > cache)
{
cache = value;
return true;
}
return false;
}
int get() const
{
return cache;
}
virtual void someInterface() const = 0;
};
Deriving from this class gives You the functionality of the base class (put and get) without the danger of breaking it (by for example writing a wrong value to cache).
Side note: Above is a purely made up example! You shouldn't add such a cache (which is independent of Your interface) into the abstract base class. As it stands the example breaks with the "Single Responsibility Principle"!
Just because a class is abstract doesn't mean there cannot be code implemented in that class that might access that variable. When you declare an item in a class to be private, the compiler assumes you had a good reason and will not change the access just because it there is a pure virtual function in the class.
If you want your derived classes to have access to a base class member declare the member as protected.
I have an abstract class base with private member variable base_var
class foo {
public:
virtual void a_pure_virtual_method() = 0;
int get_var() { base_var; }
virtual ~foo(){}
private:
int base_var;
};
Note that a class is said to be abstract when it has at least one pure virtual (aka abstract) method. There is nothing that forbids an abstract class to have non-pure virtual or even non-virtual methods.
I want to create a derived class, which also has base_var as a private member.
class derived : public foo {};
To me, this seems like an obvious thing you would want to do.
Sure, no problem so far.
The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
Still fine.
Why not?
You are confusing access rights that are display in the image you included with the mere presence of the members in the derived. The derived class has no access to members that are private in the base class. Period. This is just according to the definition of what is private.
What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
It is not useless at all. Derived classes inherit all members, they just cannot access all of them. The private stuff is there you just cannot access it directly. Thats the whole point of encapsulation. Consider this example:
class bar : public foo {
void test() {
std::cout << base_var; // error base_var is private in foo
std::cout << get_var(); // fine
}
};

C++ interface design: Private virtuals

Say I have an interface class A (class with only pure virtual functions). Also, I have a concrete class B, which holds a weak pointer to A, and calls methods on it.
There is strong coupling between classes A and B. Basically I expect only class B will call methods on class A.
Does it make sense to declare all methods on A, private (pure) virtual and make class B its friend. The classes implementing A, will be free to change the access of the functions they implement as part of inheriting A. It seems appropriate for the use case but I haven't seen it used before.
It makes sense, and it addresses one design issue, but it raises another one (which you might either consider minor or not).
In Sutter and Alexandrescu's C++ Coding Standards there's a guideline 39. Consider making virtual functions nonpublic, and public functions nonvirtual. This makes sense. Say you have
class interface {
public:
virtual void bar();
};
then you realize that all bars have something in common: maybe you want to validate arguments passed to them (if they take arguments), or log calls to all of them. Because of this, the guideline is to split it into
class interface {
public:
void bar() { bar_(); }
protected:
virtual void bar_();
};
I.e., a public non-virtual method calling a non-public virtual one. The public one is the only gateway to the virtual one.
The problem is that this is the only gateway until you introduce friend. Then, you have no control, and the external class can call bar_ directly, circumventing it.
In your case, you could consider the following, therefore:
Say the class to which you want to grant access is foo, and the interface class is interface. Write another class interface_accessor, which will be the gateway:
class foo;
class interface;
class interface_accessor {
private:
static void bar(interface &i);
friend class foo;
};
Note that interface_accessor is a friend of foo.
Now, make interface a friend of interface_accessor, but not of foo:
class interface {
private:
virtual void bar_() {}
friend class interface_accessor;
};
Finally, implement interface_accessor:
void interface_accessor::bar(interface &i) {
i.bar_();
}

Should private inheritance be used when there are no virtuals?

In C++, if I have a class Base which is a private base class of Derived but Base has no virtual functions, would it be cleaner to instead replace having inheritance with encapsulation in class Encapsulate? I imagine the only benefit to inheritance in this case would be that the base class can be accessed directly in the derived class as opposed to through memberVariable. Is one or the other practice considered better, or is it more of a personal style question?
class Base {
public:
void privateWork();
// No virtual member functions here.
};
class Derived : Base {
public:
void doSomething() {
privateWork();
}
};
class Encapsulate {
Base memberVariable;
public:
void doSomething() {
memberVariable.privateWork()
}
};
Remember that inheritance models "Liskov substitution": Foo is a Bar if and only if you can pass a Foo variable to every function expecting a Bar. Private inheritance does not model this. It models composition (Foo is implemented in terms of Bar).
Now, you should pretty much always use the second version, since it is simpler and expresses the intent better: it is less confusing for people who don't know about it.
However, sometimes, private inheritance is handy:
class FooCollection : std::vector<Foo>
{
public:
FooCollection(size_t n) : std::vector<Foo>(n) {};
using std::vector<Foo>::begin;
using std::vector<Foo>::end;
using std::vector<Foo>::operator[];
};
This allows you to reuse some of the functionality of vector without having to forward manually the 2 versions (const + non const) of begin, end, and operator[].
In this case, you don't have polymorphism at all: this is not inheritance, this is composition is disguise; there is no way you can use a FooCollection as a vector. In particular, you don't need a virtual destructor.
If there are no virtual functions, then inheritance should not be used in OO. Note this does not mean that it must not be used, there are a few (limited) cases where you might need to (ab)use inheritance for other purposes than OO.

Is it necessary the scope resolution in this case?

Do we need to include the scope
baseClass::statmember.methodmember();
in a call to a static member of the base class that has been inherited when we call it from inside a method of the derived class?
I see it in a code programed by other person, I try to modify it and it compiles as well without including the scope
derivedclass::methodDerived() {
statmember.methodmember();
};
Why the programmer has included in all the calls to the member the scope:: if its unnecessary? Is it a reminder of the unicity of the static member in all the objects?
Or I am wrong and the code may give different results?
I'm guessing it's because the following is allowed:
class Base
{
public:
static void foo(){}
};
class Derived:public Base
{
public:
static void foo(){}
};
Either that, or for readability. Sometimes, just because it isn't necessary doesn't mean it has no use (even if that use is readability, which is a biggie).
It would be necessary only if the base class and the derived class have a function with the same name, and you want to distinguish between them.
Otherwise it's not necessary.

Why won't the C++ compiler disambiguate between an inherited public and an inherited private method with the same name?

I'm confused as to why the C++ compiler won't accept this:
class Foo {
private: void Baz() { }
};
class Bar {
public: void Baz() {
};
class FooBar : public Foo, public Bar { };
void main() {
FooBar fb;
fb.Baz();
}
The error gcc gives is:
request for member ‘Baz’ is ambiguous
candidates are: void Bar::Baz()
void Foo::Baz()
but isn't it obvious that I want Bar::Baz(), since Foo::Baz() is private? Why won't the compiler disambiguate here?
Name resolution works in two stages. First the name is looked up then the name is checked for access. If the name look up is ambiguous then the access is never considered.
As to why, maybe it's a deliberate language design, but I think more likely it's just to simplify the process of resolving names. The rules are fiendishly complicated already.
It's not obvious - you might have wanted to call the private member (if that was possible).
Formally, the language rules say that the name is resolved first and the best overload is selected. Only after that is there a check for accessibility.
In order to allow this, it would need to consider whether or not you are in a context that allows you to call a private method or not. If this were allowed then the call:
fb.Baz()
could have completely different functionality depending on whether you were calling it from a public or private context. And that's not really inline with the way the language works.
As others have said, first the name is looked up, then access restrictions are applied. You can work around this by explicitly calling the method you wish, as in
fb.Bar::Baz()
Access restrictions don't affect inheritance. You always inherit everything from all base classes. In your case that may seem unnecessary, but consider a slightly modified version where the private function is virtual:
class Base
{
virtual void secret_power() { /* innocent default */ }
public:
void use_me() { secret_power(); }
};
class Derived : public Base
{
virtual void secret_power() { /* overriding implementation here */ }
};
Now for any Base& you can always call the non-virtual public interface use_me(), but your derived classes provide the implementation by means of a private virtual.