friendship from derived class method to base class members - c++

I would like to know if there's a way to make a method from a derived class a friend of its base class. Something like:
class Derived;
class Base
{
int i, j;
friend void Derived::f();
protected:
Base();
};
class Derived : public Base
{
public:
void f();
};
The errors I got were:
error: C2027: use of undefined type 'Derived'
see declaration of 'Derived'
error: C2248: 'Base::i' : cannot access private member declared in class 'Base'
see declaration of 'Base::i'
see declaration of 'Base'
error: C2248: 'Base::j' : cannot access private member declared in class 'Base'
see declaration of 'Base::j'
see declaration of 'Base'
error: C2027: use of undefined type 'Derived'
see declaration of 'Derived'
I struggled with it during all the day. Everything I found about friendship use only separated classes, not inheritance.

No there is no direct way : Base needs the definition of Derived::f while Derived also needs the definition of it's Base class.
But it does not matter, you should not do that, you can, in order of preference :
Provide protected accessors in the Base class
Make the entire Derived class a friend (not necessary in general)
You can use an intermediate helper class which only forward the call of this specific method, and give it friendship :
Example here:
class Base;
class Derived;
class Helper final
{
friend class Derived;
public:
void f(Base* base);
private:
Helper() {}
};
class Base
{
int i, j;
friend class Helper;
protected:
Base() {}
};
class Derived : public Base
{
public:
void f();
private:
Helper helper;
};
void Helper::f(Base* base)
{
base->i = 10; base->j = 5;
std::cout << "Help !" ;
}
void Derived::f()
{
helper.f(this);
}

One approach for this kind of problem is to apply the rule "if it's a thing, then it's a class."
#quantdev solution is on those lines.
Based on the comment:
assuming that I have two classes both derived from base class and
having an identical private member. Why not saving some codes by
putting that member in the base class and providing a friend access to
both derived classes that need the member. Assuming that other derived
classes won't be able to access that member at all. That's what I'm
trying to achieve
[I know that this does not answer the specified question, but may be what you need.]
I'd solve that by factoring the common element into an intermediate class:
class Base
{
public:
Base();
virtual ~Base() = 0;
};
class Derived : public Base
{
public:
void f()
{
i = 1;
}
private:
int i, j;
};
class Foo : public Derived
{};
class Bar : public Derived
{};
class Fred : public Base
{};

I don't know if it is possible to do exactly what you want (although it seems to me like it should be) -- and I'd be interested to see other answers that show how if it is -- but there are a few other ways to achieve what you want. I assume you are asking about this situation in general -- that is, you are also interested in the case where there can be many different derived classes, not all of which need, no should have access to the private fields of Base (otherwise you should make these fields protected of course).
First, the easiest thing to do would be to make Derived a friend class to Base, although this feels like a hack (in part because it doesn't allow for any encapsulation of Base with respect to Derived) and is definitely sub-optimal here.
In my opinion, a somewhat better approach in terms of encapsulation would be to make an external "free" (non-member) function that is a friend to Base (and potentially Derived if you need that too). This gets around the circular compiler error, but unfortunately still loses the conceptual semantics of being an "operation on Derived".

Related

Superclass Setting Object of Subclass Data

I have a base class in C++ that has some protected member variables (although, I do not think it is relevant that it is protected vs. private in this case).
I have a derived class that derives from this base class. In it, there is a public function that creates an object of the base class and returns that object. However, in that function I need to be able to set the protected member variables into a special state.
Example:
class Base
{
protected:
int b_value;
};
class Derived : public Base
{
public:
Base createBase()
{
Base b;
b.b_value = 10;
return b;
}
};
I specifically only want the derived class to be able to the protected member variable. I do not want a public accessor method in the base class.
I originally tried to fix this by making the derived class's createBase() function be a friend of the Base class. Like so:
class Base
{
protected:
int b_value;
friend Base Derived::createBase();
};
class Derived : public Base
{
public:
Base createBase()
{
Base b;
b.b_value = 10;
return b;
}
};
As you can see, this will not compile since Derived has not been defined yet. If it matters, these two classes are defined in separate header files. I guess one way to describe this problem is a "chicken and egg" problem where one needs the other first.
I have a feeling this has to be a "I am not designing my classes correctly and need to rethink how I am doing this" but I cannot figure out how to get this to work.
You can forward declare Derived and then make it a friend in Base :
class Derived;
class Base
{
friend class Derived;
protected:
int b_value;
};
class Derived : public Base
{
public:
Base createBase()
{
Base b;
b.b_value = 10;
return b;
}
};
However this design seems seriously flawed to me as you already stated, you should probably make createBase() a static public method in your Base class and have a setter for b_value or a constructor that sets it.
Remember that right now inside createBase(), this->b_value is also available.

Polymorphism->error: 'no known conversion from derived class to base class'

How can I possibly do this:
class Base
{
public:
int a, b, c;
void function();
...
};
class Derived1 :
private Base
{
public:
int d, e, f;
...
};
class Derived2 :
private Base
{
public:
void addObject(const Base* obj);
...
};
Note that I inherit it as private
Then I would like to do like:
Base* d1 = new Derived1();
Base* d2 = new Derived2();
d2->addObject(d1);
And here is the relevant issue I am getting from the compiler:
C:\test\test.cpp||In function 'void init()':|
C:\test\test.cpp|423|error: no matching function for call to 'Derived2::addObject(const Base*)'|
C:\test\test.cpp|423|note: candidate is:|
C:\test\test.h|29|note: void Derived2::addObject(const Base*)|
C:\test\test.h|29|note: no known conversion for argument 1 from 'Derived1 {aka ... }' to 'const Base* {aka ... }'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 9 seconds) ===|
The reason I want to inherit the Base as private by some derived classes is to hide some Base's members/functions in public scope.
I do not want to directly access some Base::functions() in a public scope but else, used a Derived::function() instead to manipulate its data members and let the derived class decide what action it would perform.
However, I could think of overriding each function from base class that I do not want to modify directly in public scope but its not flexible and too many in my case.
What I mean is:
class Base
{
public:
//I must think in advance deciding whether if it'll be virtual or not.
[virtual] void f1(int);
[virtual] void f2(int);
[virtual] void f3(int);
//and many more...
};
class Derivedn :
private Base
{
public:
//hmm, I should not neglect to override certain base' member functions
//that I don't want to access in public scope.
void f1(int);
};
I want to avoid this but...
Is there any other way I can do, similar to this one, without overriding each Base::function()s?
The reason this does not work is that inheriting privately does not constitute an "is a" relationship. In fact, is a lot closer to composition than inheritance, because the derived class acquires the implementation of the base without acquiring its interface.
The reason I want to inherit the Base as private by some derived classes is to hide some Base's members/functions in public scope.
That is a wrong reason to inherit privately. Here are some good answers to the question when you should inherit privately.
Is there any other way I can do, similar to this one, without overriding each Base::function()s?
You are not required to override every single one of the Base's functions, unless they are pure virtual (also known as "abstract") ones. Your base class can provide empty implementations for its virtual functions, so that the derived classes could decide which functionality to provide.
I think your code should read:
d2.addObject(&d1); // Note the "&"
As the compiler says, there is no possible conversion from an instance of Derived1 to a const pointer to an instance of Base.
Not sure what you wanna, but polymorphism do exactly that, allow you to override a base function in Derived class:
class Base
{
public:
int a, b, c;
virtual void function();
^^^^^^^
...
};
class Derived1 :
public Base
{
public:
int d, e, f;
virtual void function(); // do derived version of Base::function
};
and now you can access Derived version of function from Base objects

C++ inheritance: Can't access private element of base class

I have a base class:
class Base
{
public:
functions...
private:
std::vector<float> privateElement;
}
and a derived one:
class Derived : public Base
{
public:
functions...
Derived(anotherElement) : privateElement(anotherElement)
{
}
}
My problem now is that everytime I try to build my project, the compiler (gcc 4.7.2) always complains about not being able to access privateElement, like:
class Derived does not have any field named privateElement
std::vector<float> Base::privateElement is private
May anybody help me here?
First of all, private members of base class are not accessible from derived class.
Now even if you fix that and make it protected (or public), then this will still be ill-formed, because you cannot initialize the base's members in the derived class's mem-init-list. It doesn't make sense, because by the time the derived class mem-init-list executes the base's members are already initialized, and the syntax : protectedElement(xyz) will make the compiler think that protectedElement is a member of the derived class, not of the base class!
See this error even after making it protected:
main.cpp: In constructor ‘Derived::Derived(std::vector<float>)’:
main.cpp:20:37: error: class ‘Derived’ does not have any field named ‘protectedElement’
Derived(std::vector<float> v) : protectedElement(v)
^
Online demo
The right way to do this is to define a constructor for the base class, and call this from the derived class initialization-list.
Hope that helps.
The right way to do it without breaking encapsulation would be for the base class to provide a constructor which we can call from derived class :
class Derived : public Base
{
public:
functions...
Derived(anotherElement) : Base(anotherElement)
{
}
}
class Base
{
public:
Base(anotherElement):privateElement(anotherElement) { }
private:
std::vector<float> privateElement;
}
Derived class cannot access private parts of the base class. That's because they are, well, private. Use protected if you want the derived class to have access to the base class' members without breaking the encapsulation.

Public and private inheritance in C++

As we know from the literature for the public inheritance the object of child class (sub-class) also can be considered as the object of base class (super-class). Why the object of the sub-class can’t be considered as an object of super-class, when the inheritance is protected or private?
Because you can't see it:
class Base
{
public: virtual ~Base() {}
};
class PublicDerived: public Base
{ };
class PrivateDerived: private Base
{ };
int main()
{
PublicDerived publicD;
PrivateDerived privateD;
Base& base1 = publicD;
Base& base2 = privateD; // ERROR
}
So you can not use a PrivateDerived object where a Base object could be used.
So it will never act like a Base class object.
In general you will find in literature (and in other answers here) that protected/private inheritance imply that the class cannot be used as a base. The fact (some other answer hints into this) is that only the visibility of the inheritance is affected by the operation. The derived class is a base class, even if external code cannot see it.
Any friend or the class will be able to make use of that relationship:
struct base {
virtual void foo() { std::cout << "base" << std::endl; }
};
void take_base( base& b ) {}
class derived : base // private {
friend base& to_base( derived& );
virtual void foo() { std::cout << "derived" << std::endl; }
public:
base & as_base() { return *this; }
void call_function() { take_base(*this); } // ok: inside derived, it knows that it is
// in fact a base
};
base& to_base( derived& d ) {
return d;
}
int main() {
derived d;
//d.foo(); // error
//take_base(d); // error
take_base( d.as_base() ); // ok, the conversion is performed internally where
// access is granted: print "derived"
take_base( to_base(d) ); // ok, the conversion is performed in a friend function
// that has access: print "derived"
}
Now, while technically this is the case, semantically when you use private inheritance you are trying to model not an is-a but rather a implemented-in-terms-of relationship. This is the important part: while reading code, if you see private inheritance you should not think on is-a but implemented-in-terms-of.
In brief, because private inheritance is inheritance of implementation, not that of interface. A private subclass Derived object is not a Base, but is implemented in terms of Base. The public and protected members of Base are visible for Derived, but they become private, thus inaccessible for the outside world. Thus private inheritance can be thought of as a special form of composition, which is in fact rarely needed in practice. (And protected inheritance is practically never - in fact probably even Bjarne Stroustrup doesn't know what protected inheritance means.)
The "why" is simple when considering how the mechanism works: because protected and private inheritance are meant to work that way.
This is probably not enough to answer the question's intent though. You might ask "and why have private and protected inheritance if you can't use the resulting objects as instances of the base class?"
Well, non-public inheritance is meant to facilitate the "is implemented in terms of" relationship between two classes (whereas public inheritance facilitates the "is-a" relationship). In other words, you intend to reuse part or all of the base class functionality to provide services to your own consumers.
This scenario is almost always better implemented by aggregation instead of inheritance (i.e., having a member object of the "base" class), and I would go so far as to say that non-public inheritance is something better left alone.
Take a look at this for a longer write-up that expands on the above.
Update: as the commenters below state, there are some (admittedly rare) cases where non-public inheritance provides the mechanism for architectural functionality that would not otherwise be possible. Do read them, as exploring the edges of a language can be quite enlightening. But try to do it as little as you can anyway.
public inheritance serves the purpose of the is-a relationship. That is:
class A {};
class B : public A {};
Class B is a version of class A.
private inheritance serves the purpose of the has-a relationship. You can write almost any class using private inheritance using a container model instead:
class A {};
class B : private A {};
can be rewritten (and more often than not, should be rewritten for clarity):
class A {};
class B
{
private:
A a;
};
protected inheritance is similar to private, but in reality should almost never be used (Scott Meyers and Herb Sutter both give reasons for this in their respective books).
You can think of public / protected / private inheritance like accessibility for any class member : it a matter of 'how much you want to show'.
A private (or protected, in a slightly different way) inheritance is a relationship which is not shown the outside world. As such, you can't treat an object of a derived type as its private base, because you don't get to "see" that this relationship even exists.
Why the object of the sub-class can’t
be considered as an object of
super-class, when the inheritance is
protected or private?
It can certainly be considered an object of the super-class. However, such consideration is restricted (by the public/protected/private inhertiance modifier) to but only by itself (private inheritance) or it's sub-classes (protected inheritance).
All external objects are not allowed to considered the class as such, similar to how they not allowed to access protected or private methods or variables. The analogy is rather fitting, if expressed properly.
So, the class itself, its subclasses (and friends) can see this as an is-a relationship, but the outside world is not permitted to do so.
The following code shows this in action:
class Base {
public: virtual ~Base() {}
};
class PublicDerived: public Base
{ };
class ProtectedDerived: protected Base {
void test() {
Base* base2 = this; // OK
}
};
class ProtectedSubClass: public ProtectedDerived {
void test() {
Base* base2 = this; // OK
}
};
class PrivateDerived: private Base {
void test() {
Base* base2 = this; // OK
}
};
class PrivateSubClass: public PrivateDerived {
void test() {
Base* base2 = this; // Error (line 28)
}
};
int main()
{
PublicDerived publicD;
ProtectedDerived protectedD;
PrivateDerived privateD;
Base* base1 = &publicD;
Base* base2 = &protectedD; // Error (line 39)
Base* base3 = &privateD; // Error (line 40)
}
Note that it doesn't matter how the xxxSubClass-classes derive from their super-classes. It's all about how the super-classes derive from Base, which is as it should be.
The compiler complains appropriately:
inherit.cpp(28) : error C2247: 'Base' not accessible because 'PrivateDerived' uses 'private' to inherit from 'Base'
inherit.cpp(1) : see declaration of 'Base'
inherit.cpp(20) : see declaration of 'PrivateDerived'
inherit.cpp(1) : see declaration of 'Base'
inherit.cpp(29) : error C2243: 'type cast' : conversion from 'PrivateSubClass *const ' to 'Base *' exists, but is inaccessible
inherit.cpp(39) : error C2243: 'type cast' : conversion from 'ProtectedDerived *' to 'Base *' exists, but is inaccessible
inherit.cpp(40) : error C2243: 'type cast' : conversion from 'PrivateDerived *' to 'Base *' exists, but is inaccessible

Enforce use of scope resolution operator when accessing base class member from derived class

I have a class Derived which is derived from class Base. In Derived's function, I can access protected members of Base. E.g., I can do this.
class Base
{
protected:
int i;
}
class Derived : class Base
{
void process()
{
i = 5;
}
}
My question is, is it possible to enforce the use of scope resolution operator when accessing base class member from derived class? The reason is that I want to make it clear in the code which variables are from the base class. The enforcement is so that I won't accidentally skip the scope resolution operator (I'm careless). I prefer not to use accessors since many members from the base class are required in the Derived class, making it tedious to code. I'm using MSVC 2010 by the way.
class Base
{
protected:
int i;
}
class Derived : class Base
{
void process()
{
Base::i = 5; //enforce so that i=5 won't compile
}
}
you can simulate it by introducing another scope:
class Base {
protected:
struct Data {int i;};
Data d_Base;
};
class Derived : class Base {
void process() {
d_Base.i = 5;
}
};
You cannot do it in the base class itself, no, there is no way you could enforce that. However, I am thinking of a trick which you could do in a derived class to enforce what you want, that is, if you declare a variable with the same name i in the derived class as a member, but of type, say, MyBadType, which is just an empty type, then i in derived will refer to it and there is really nothing the user could do with it. So he will HAVE TO qualify to get the base i. But this is naturally a joke, I mean, you don't want to fatten the size of your derived class just to enforce qualified names. Your goal itself is a bit dubious.
HTH,
Armen