I have an abstract class AUnit with variables and getters/setters in virtual pure like this
class AUnit {int var... int getVar() const = 0 ... }
All the data is in protected: except constructor and destructor.
I have Berserk and Tank as child like this
class Berserk : public AUnit
{
...
private:
int getVar() const;
In their .cpp, I write the code of the getters and setters. Nothing special.
But I have one other class (foo for example) like this
class Foo : public Berserk, public Tank
who need to access the data in Berserk or Tank so I changed the private keyword by protected, here is the error :
Tank.hpp:36:25: erreur: ‘virtual int Tank::getY() const’ is protected
error inside the context
As first, I just tried to access the data with the AUnit getter but cause of virtual pure and abstract concepts, I thought to reinterpret_cast my AUnit in his real type after passing getType of AUnit in non-pure and in public. Still not working, its the scheme I told you earlier.
It's just classical heritage, can I have some help ?
Your code snipped is certainly incomplete. My guess is that you have something like this:
int Foo::f(Tank const* tank) {
return tank->getY();
}
(probably, you are doing something more interesting with value than returning it).
Even though access to Tank::getY() is protected, the class Foo won't have access to getY() in the above code because the object pointed to by tank is not known to be a Foo object: a class has only access to protected members in a base object of its own type! That is, the following would be OK:
int Foo::f(Foo const* foo) {
return foo->getY();
}
So far the only good use I have found for protected a virtual member functions which have a reasonable an non-trivial implementation in a base class and which are called from a [further] derived class as part of overriding the member. This way, functionality can be added and the common logic can be used (of course, any virtual function is not public but rather private or protected).
It is generally a bad idea to give the overriding function a stricter access protection than the function it overrides. Consider:
class Base {
public:
virtual void f() {}
};
class Derived : public Base {
private:
virtual void f() {} // overrides Base::f
};
Derived d;
d.f(); // error - f is private
Base* pb = &d;
pb->f(); // OK - calls d.f()
To avoid such paradoxes, it is prudent to put overrides at the same access level as the original (or the more relaxed access level, though that's somewhat unusual).
Related
Is there any point to making virtual member functions, overridden from a base class private, if those are public in the base class?
struct base {
virtual void a();
};
struct derived : base {
// ...
private:
void a() override;
};
If you are forced to do a 2-phase construction on the implementation class (i.e. have an init() method as well as or instead of a constructor that has to be called (I know, but there are reasons), then this stops you calling any /other/ methods directly on the instance pointer before you pass it back as an interface pointer. Go the extra mile, make the inheritance private, and have your one public init function return the interface pointer!
Another reason is you just don't /need/ to write public: in a final implementation class declaration, so then by default everything is private. But why you would do that and use struct instead of class I don't know. Perhaps this was converted from class at some point due to a style war?
Looking at your design, I see one cannot call derived::a directly, but only through a base interface.
Is there any point? Consider that, once we have a derived instance, we can always up-cast to its base, so given
derived d;
while d.a() wouldn't compile, we can always do
base & b = d;
b.a(); //which actually calls derived::a
In other words: derived::a is not that private, after all, and I would discourage this design, which can be confusing to the user.
Things change if the members private in derived are private in base, as well: this time it is clear that they just cannot be called directly, outside base or derived.
Let's say we have a couple of functions, and want them to be called conditionally, according to a value passed as an argument to a third one:
struct base
{
void dosomething(bool x)
{
if(x)
{
do_this();
}
else
{
do_that();
}
}
private:
virtual void do_this(){}
virtual void do_that(){}
};
Thus a derived class could be like:
struct derived : base
{
private:
void do_this() override { }
void do_that() override { }
};
and no other class can call them, unless it extended base itself:
derived d;
d.dosomething(true); //will call do_this() in derived
d.dosomething(false); //will call do_that() in derived
d.do_that() //won't compile
Yes, if you inherit the base class as private. Otherwise, it is more of a weird explicit-like restriction - user has to has to make an explicit conversion to use the function - it is generally ill advised as few will be able to comprehend the author's intention.
If you want to restrict some functions from base class, make a private/protected inheritance and via using keyword declare which base-methods you want to be protected/public in the derived class.
The same reasoning as for non-virtual methods applies: If only the class itself is supposed to call it make it private.
Consider the template method pattern:
struct base {
void foo() { a() ; b(); }
virtual void a() = 0;
virtual void b() = 0;
};
struct derived : base {
private:
void a() override {}
void b() override {}
};
int main()
{
derived().foo();
}
Perhaps a and b should have been protected, but anyhow the derived can change accesibility and it requires some documentation so that derived knows how it is supposed to implement a and b.
I just find out that overriding a private function to a public one from base object is allowed in C++ since Visual Studio produces 0 warning. Is there any potential danger to doing that?
If there isn't, what's the difference between declaring a virtual function in private, protected and public in a base object?
what's the difference between declaring a virtual function in
private, protected and public in a base object?
The difference is that a private virtual function can be called only from a base class. This can be useful if the function is not a part of an external class interface, and is only used by base class. So that users call (some other) base class' member, and that member calls the virtual function. For example:
class Base {
virtual void stage1()=0; // derived classes override this
virtual void stage2()=0;
public:
void run() { stage1(); stage2(); } // users call this
};
Moreover, there is a point of view that you should not make your virtual functions public at all, because the fact that they are virtual is internals of the class and its subclasses, and the users should not be aware of that. It is rarely that the same function must be overridden and callable from external code. This allows the base class to control which (virtual) functions can be called from which (non-virtual) public method, making maiteinance easier.
See more details in this article by Herb Sutter:
...each [public] virtual
function is doing two jobs: It's specifying interface because it's
public...; and it's specifying implementation detail,
namely the internally customizable behavior... That a public virtual
function inherently has two significantly different jobs is a sign
that it's not separating concerns well and that we should consider a
different approach. What if we want to separate the specification of
interface from the specification of the implementation's customizable
behavior?
...
In summary, prefer to make base class virtual functions private (or
protected if you really must). This separates the concerns of
interface and implementation, which stabilizes interfaces and makes
implementation decisions easier to change and refactor later.
However, I am not qualified to say whether this is really widely used...
Is there any potential danger to doing that?
I don't think so, because you are still very limited:
class Base
{
private:
virtual void foo(){}
};
class Derived1 : public Base
{
public:
virtual void foo(){ Base::foo(); }
};
class Derived2 : public Base
{
public:
virtual void foo(){}
};
int main()
{
Derived1 d1;
d1.foo(); //error
Base * d2 = new Derived2();
d2->foo(); //error
}
So at best you will be able to call the overloaded function (if it doesn't call the function from the base class from itself), but the function of the base class will still have the same visibility, and will be inaccessible.
When changing access visibility by overriding in derived class, base class visibility doesn't change:
So with:
class Base {
public:
virtual ~Base() = default;
protected:
virtual void foo() = 0;
};
class Derived : public Base {
public:
void foo() override {};
};
Then
Derived d;
Base& b = d;
d.foo(); // valid
b.foo(); // invalid
If there isn't, what's the difference between declaring a virtual function in private, protected and public in a base object?
It depends on how you access the function. The type of the object/pointer you use determines whether you can access the function.
class Base
{
public:
virtual void foo() {}
};
class Derived : public Base
{
private:
virtual void foo() {}
};
int main()
{
Derived* dptr = new Derived;
Base* bptr = dptr;
dptr->foo(); // Can't use it. Derived::foo is private
bptr->foo(); // Can use it. Base::foo is public.
}
Compiler message, using g++ 4.9.3.
socc.cc: In function ‘int main()’:
socc.cc:12:20: error: ‘virtual void Derived::foo()’ is private
virtual void foo() {}
^
socc.cc:20:14: error: within this context
dptr->foo(); // Can't use it. Derived::foo is private
A virtual function is a customization point for derived class implementations. If it is private then it's purely an implementation detail. Making it more accessible in a derived class then exposes an implementation detail, with all that that entails. In particular client code can come to depend on that detail so that the implementation can't be easily changed. It can also be easier for client tode to call in incorrect ways, than the originally intended interface, and it can yield results that are only valid in certain contexts, so that it's more brittle than the original interface.
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
Here is a sample of code that annoys me:
class Base {
protected:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base *b; /* Initialized by constructor, not shown here
Intended to store a pointer on an instance of any derived class of Base */
protected:
virtual void foo() { /* Some implementation */ };
virtual void foo2() {
this->b->foo(); /* Compilator sets an error: 'virtual void Base::foo() is protected' */
}
};
How do you access to the protected overrided function?
Thanks for your help. :o)
Protected members in a base-class are only accessible by the current object.
Thus, you are allowed to call this->foo(), but you are not allowed to call this->b->foo(). This is independent of whether Derived provides an implementation for foo or not.
The reason behind this restriction is that it would otherwise be very easy to circumvent protected access. You just create a class like Derived, and suddenly you also have access to parts of other classes (like OtherDerived) that were supposed to be inaccessible to outsiders.
Normally, you would do it using Base::foo(), which refers to the base class of the current instance.
However, if your code needs to do it the way you're trying to and it's not allowed, then you'll need to either make foo() public or make Derived a friend of Base.
One solution would be to declare a static protected function in Base that redirects the call to the private / protected function (foo in the example).
Lets say:
class Base {
protected:
static void call_foo(Base* base) { base->foo(); }
private:
virtual void foo() = 0;
};
class Derived : public Base {
private:
Base* b;
protected:
virtual void foo(){/* Some implementation */};
virtual void foo2()
{
// b->foo(); // doesn't work
call_foo(b); // works
}
};
This way, we don't break encapsulation because the designer of Base can make an explicit choice to allow all derived classes to call foo on each other, while avoiding to put foo into the public interface or explicitly turning all possible subclasses of Base into friends.
Also, this method works regardless of whether foo is virtual or not, or whether it is private or protected.
Here is a link to a running version of the code above and here another version of the same idea with a little more business logic.
It's a bit fragile, but with the classes you defined here, won't this work?
virtual void foo2() {
reinterpret_cast<Derived *>(this->b)->foo();
}
The reinterpret_cast points at the VTABLE for the base object, and calls it through this members accessor.
You call base functions explicitly with the scope operator (Base::foo()). But in this case, the Base class doesn't define foo (it's pure virtual), so there's actually no function to execute when you say this->b->foo(); since b is a pointer to Base and not Derived.
How do you access to the protected
overrided function?
--- from where?
You can access a protected member only via inheritance (apart from the methods of the same class). Say for example you have a class Derived1 which inherits from Derived, then objects of Derived1 can call foo().
EDIT: MSDN article on protected access specifier.
Suppose I want to have an inheritance hierarchy like this.
class Base
class DerivedOne : public Base
class DerivedTwo : public Base
The base class is not meant to be instantiated, and thus has some pure virtual functions that the derived classes must define, making it an abstract base class.
However, there are some functions that you would like your derived classes to get from your base class. These functions modify private data members that both DerivedOne and DerivedTwo will have.
class Base {
public:
virtual void MustDefine() =0; // Function that derived classes must define
void UseThis(); // Function that derived classes are meant to use
};
However, the UseThis() function is meant to modify private data members. That's where the question comes in. Should I give the Base class dummy private data members? Should I give it protected data members (and thus the derived classes won't declare their own private data members). I know the second approach will decrease encapsulation.
What is the best approach to a situation like this? If a more detailed explanation is needed I'd be happy to provide it.
If those member variables are supposed to exist in all derived classes then you should declare them in the base class. If you are worried about encapsulation, you can make them private and provide protected accessor methods for derived classes.
Another five cents: the good practice is to have abstract interface class which has no other members, but only public pure virtual methods and often public virtual destructor. Then you create base implementation which can also be abstract but can have protected fields, etc.
In you case it would be something like:
class IBlaBla;
class BlaBlaBase : public IBlaBla;
class DerivedOne : public BlaBlaBase
class DerivedTwo : public BlaBlaBase
This allows you to have more flexibility in the future if you decide that Base is no longer good for some specialized task.
Should I give the Base class dummy
private data members?
If you can implement a part of functionality without exposing the details to the derived classes, then do it in base class. If your derived classes would need access to these members, provide setters and getters. However, it is not convenient to have setters available for derived classes because your code becomes tightly coupled.
Encapsulation is sometimes overrated. If your base class and derived classes need to access those members, then they should probably be protected, not private. If it really is something that needs to be encapsulated, then you may want to make them private but provide getters and setters (either make them private to Base, with getters and setters defined there, or private to the derived classes, with pure virtual getters and setters in Base).
It's a bit hard to give you more specific advice without knowing about the actual problem you're trying to solve.
You will have to define Base::UseThis(), in the body of which you will make use of Base's fields (which you will also need to declare in the class definition above). If you only need to access them in UseThis, they can be private. If DerivedOne/Two will need access to them, you should make them protected.
Here is a possible resolution to your dilemna:
class Base {
public:
virtual ~Base() {}
virtual void redefine_me() = 0;
void utility_function();
private:
virtual int get_data_member() = 0;
virtual void set_data_member(int v) = 0;
};
class Derived1 : public Base {
public:
virtual void redefine_me() { do_d1_stuff(); }
private:
int my_private_idaho_;
virtual int get_data_member() { return my_private_idaho_; }
virtual void set_data_member(int v) { my_rpviate_idaho_ = v; }
};
class Derived2 : public Base {
public:
virtual void redefine_me() { do_d2_stuff(); }
private:
int gomer_pyle_;
virtual int get_data_member() { return gomer_pyle_; }
virtual void set_data_member(int v) { gomer_pyle_ = v; }
};
void Base::utility_function()
{
set_data_member(get_data_member() + 1);
}
It's biggest disadvantage is that now access to the private data member is mediated by a virtual function call, which isn't the cheapest thing around. It's also hidden from the optimizer.
This means that if you choose it, you should adopt a pattern where you fetch the private data member into a local variable at the beginning of your utility function and set it from the local variable before you return. Of course some utility functions may call out to functions that require the object state to be updated before they're called, and this pattern would then have to be modified to account for that. But then again, such utility functions are likely not to be able to satisfy the strong exception handling guarantee and should be rethought anyway.
It looks as if you need some interface for client code, and some 'convenient' functionality for implementors of the interface, which they can only use if they follow the rule of calling the useThis function of the convenience layer, which will tweak their private members.
Whenever I gave in to the temptation of putting the convenience functionality in my abstract base class, I regretted it (soon!) afterwards. It takes away a lot of flexibility. The solution proposed by AlexKR makes this situation slightly better.
An alternative way of doing this is providing some convenience class that implementers of the interface can aggregate instead of inheriting it. It can provide a function taking the implementer's members as arguments.
class Interface { public: virtual void f() = 0; };
class Convenience {
public:
void tweakMyMembers( int& member1, float& member2 );
bool somestate;
};
class Implementor : public Interface {
int m1; float m2;
public: Implementor( bool b ): conv( b ) {}
virtual void f() { conv.tweakMyMembers( m1, m2 ); if( m1<m2 ) dothis(); }
};