How can ensure that only "my" code can use a class, even if it is used a base class? (If it's not used as a base class I can make it a private or protected nested class of one of my classes)
If I want to indicate that use of a base class for one of my classes is a mere implementation detail, I can use a private base class:
class Base
{
...
}
class Derived: private Base
{
public:
Derived(...): Base{...} {... };
...
}
To clients of my Derived class, that I used the Base class is not apparent:
#include "Derived.h"
void client() {
Derived d{...};
Base *b = static_cast< Base * >(&d);// error
...
}
But imagine that the Base class is so specialised, or confusing, or tricky to use, that I don't want it to be possible for clients of my code to use it as a base class or create objects of that class. I want it to be "private", in some sense, to some of my code, so client code like this fails:
#include "Derived.h"
class Client: Base// error wanted here
{
public:
Client(...): Base{...} {...};
...
}
void client()
{
Derived d{...};// OK
Base b{...};// error wanted here
Client c{...};// error wanted here
}
How can I do that?
In effect, I am asking how can I achieve something like Java's package-private classes, which are accessible to only other classes in the same "package" (module), but can not be used by code outside the "package".
You can "enforce" this by convention, by placing the "private" entities into a detail namespaces. Many popular libraries (e.g. Boost) do this:
namespace detail
{
class Base { /* ... */ };
}
class Derived : private detail::Base
{
/* ... */
};
When modules will be standardized this problem will be solved properly, as you will be able to control what entities get exported and which ones are implementation details.
This can't be done directly as you would do in Java. If it's only a matter of avoiding confusion you can move Base inside a namespace which is meant to be ignored by clients of your code, eg:
namespace hidden {
class Base {
..
};
}
class Derived : private hidden::Base {
...
};
If instead you really want to avoid the possibility of using Base then it's quite a difficult story if you plan to use Base as a parent of multiple classes (which amount could vary over time). You could give Base a private constructor, and indicate that each of your derived classes is a friend of Base:
class Hider {
private:
Hider() = delete;
class Base {
..
};
friend class Derived;
};
class Derived : Hider::Base {
..
};
Of course this requires manual maintenance for each new class you want to derive from Base.
If you want to enforce it 100%, and don't like the python method of" please don't use things that start with '_'" then I believe this is your port of call:
class Dave;
class MyPrivateBaseClasses {
private:
MyPrivateBaseClasses(); // ensure nothing can use this class
class BaseClassA {};
friend Dave;
};
class Dave : public/private MyPrivateBaseClasses::BaseClassA
{};
Sure - it means you have to friend everything that wants to use it, but it does give you exactly what you wanted; 100% protection against people using BaseClassA.
Related
I have the following typical scenario, in which I want to hide implementation details in a child class, and expose it through an interface:
template <typename Derived>
class Interface
{
public:
void a()
{
static_cast<Derived*>(this)->_a();
}
};
class Implementation : public Interface<Implementation>
{
protected:
void _a()
{
/*
...
*/
}
};
I think I understand why this doesn't work, and I know that declaring the class Interface as friend of Implementation solves it, but when it comes to more complex hierarchies, like multiple interfaces, and various levels of inheritance(as is my real case), things get really messy.
I would like to avoid having to declare friend class Interface<Implementation> in each class that implements an interface.
Is there an alternative nice-and-clean solution for this problem?
Thanks!
How about using virtual functions and polymorphism?
Create an object in your child class and reassign it to an interface class pointer or reference. Then create a pure virtual function in your interface class and define it in your child class.
I have the following base template class.
template<typename T>
class Base {
public:
void do_something() {
}
};
It is intended to be used as a curiously recurring template pattern. It should be inherited like class B : public Base<B>. It must not be inherited like class B : public Base<SomeoneElse>. I want to statically enforce this requirement. If someone uses this wrong, I expect an error in the compiling phase.
What I'm doing is putting a static_cast<T const&>(*this) in do_something(). This way the class inheriting the template is or inherits from the class provided as the template parameter. Sorry for the confusing expression. In plain English, it requires B is or inherits from SomeoneElse in class B : public Base<SomeoneElse>.
I don't know if it's the optimal way to achieve this. Looks gross to me.
However I want to do more. I want to ensure B is SomeoneElse itself. How can I do that?
Make the constructor (or destructor) of Base private, and then make T a friend. This way the only thing that can construct/destruct a Base<T> is a T.
If your class contains some code that says:
T* pT = 0;
Base *pB = pT;
Then there will be a compiler error if T is not assignment-compatible with Base.
This kind of check is formalised in C++11 so you don't have to write it by hand and can get helpful error messages:
#include <type_traits>
template<typename T>
class Base {
public:
void do_something()
{
static_assert(
std::is_base_of<Base, T>::value,
"T must be derived from Base");
}
};
class B : public Base<B> { };
int main()
{
B b;
b.do_something();
}
As to ensuring that Base's type parameter is exactly the class that is deriving from it, that seems conceptually flawed. A class that is acting as a base class can't "talk about" the type that is inheriting it. It may be inherited more than once via multiple inheritance, or not at all.
Two good answers so far. Here is another which uses the idiom of generating custom access keys to certain methods (in this case a constructor). It provides an absolute guarantee of correct use while not exposing private methods in the base to the derived.
It can also be used to control access to other methods in the base class on a case-by-case basis.
template<class Derived>
struct Base
{
private:
// make constructor private
Base() = default;
protected:
// This key is protected - so visible only to derived classes
class creation_key{
// declare as friend to the derived class
friend Derived;
// make constructor private - only the Derived may create a key
creation_key() = default;
};
// allow derived class to construct me with a key
Base(creation_key)
{}
// other methods available to the derived class go here
private:
// the rest of this class is private, even to the derived class
// (good encapsulation)
};
struct D1 : Base<D1>
{
// provide the key
D1()
: Base<D1>(creation_key())
{}
};
I have several derived classes (e.g. DerivedX, where x is derived class number) that differ in fields and member functions.
Than I want to extend each derived class with some set of properties (can be organised as a field Extension ex), preserving each DerivedX class. The latter means, that we could create "clear" DerivedX objects that would not contain the property Extension ex.
The derived objects are created in some code place (e.g., in function main()), than, if they possess an extended functionality, this functionality should be used (get,set, other methods are called from main()).
The first idea was to add this new property to every derived class forming new class (ExtendedX) for each of derived classes. But I feel the code would become bulky, it seems, this approach is bad:
class Base
{
protected:
int b;
...
}
class Derived1: public Base
{
protected:
int d1;
...
};
class Derived2: public Base
{
protected:
int d2;
...
}
...X classes defined
class Extended1: public Derived1
{
protected:
Extension ex;
public:
int getExProperty1(){return ex.getProperty1();} // the realization could differ: we could also return copy of Extension object, pointer, set every field separately or the whole Extension object
}
class Extended2: public Derived2
{
protected:
Extension ex;
public:
int getExProperty1(){return ex.getProperty1();} // the realization could differ: we could also return copy of Extension object, pointer, set every field separately or the whole Extension object
}
...X classes defined
The demanded functionality is repeated in each class in that case. It's highly deprecated practice.
The other (second) idea was to declare "class Extension" that would contain the property considered ("Extension ex" in the example) and create its objects on-demand along with the objects of classes DerivedX, when we need DerivedX objects to possess this property.
The third idea was to include pointer to Extension as a field to the Base class and simply initialize it to NULL when we don't want to use the extended functionality. But then, how can we call methods of Extension class from main()?
Extended functionality could also be different in the future (derived classes are extended in accordance with the kind of problem being solved), that's why the second and the third ideas are also better, than the first.
Is there any good solution to add pack of properties and functionality to multiple derived classes?
EDIT1:
I tried to implement mixin through CRTP, as suggested by Deduplicator.
However, the code fails with:
«class Base» has no member named «getProperty1»
«class Base» has no member named «setProperty1»
The code:
#include <iostream>
using namespace std;
class Base {
int a;
public:
virtual ~Base(){}
};
class Derived1: public Base
{
public:
virtual ~Derived1(){}
};
template <class T> class Extension: public T
{
int prop1;
public:
void setProperty1(int _p){prop1=_p;}
int getProperty1(){return prop1;}
};
int main()
{
Base* der = new Derived1();
Base* e = new Extension<Derived1>();
e->setProperty1(10);
cout<< e->getProperty1();
delete der;
delete e;
return 0;
}
Changing
e->
to
static_cast<Extension<Derived1> *>(e)->
makes the code working.
How to use Extension class objects right in this case?
Use the CRTP:
// Classes implementing additions
template<class T> class Extended : public T /*, potentially additional bases */ {
// Common extension here.
}
Another option, if you can redefine the various Derived classes but can't change the definition of Base, is to shove Extension into the class hierarchy between them and Base:
class Base
{ // ...
};
class Extension: public Base
{ // ...
};
class Derived1: public Extension
{ // ...
};
class Derived2: public Extension
{ // ...
};
This way, anything that doesn't need the new APIs in Extension can continue to use Base*, and the parts that need the new API can use Extension* (or dynamic_cast<Extension>(baseptr)) instead.
This assumes Extension needs access to Base. If it doesn't, then you can just implement Extension as a mixin:
class Base
{ // ...
};
class Extension
{ // ...
};
class Derived1: public Base, Extension
{ // ...
};
class Derived2: public Base, Extension
{ // ...
};
Composition or inheritance ?
when we need Derived objects to possess this property.
This sounds as if an object and its extended property have a "has-a" and not and "is-a" relationship. This would suggest composition rather than inheritance as solution.
"on demand" , "if we don't want" ...
These suggest an optional relationship. It sounds as if you'd decide at runtime and for each object if the extension is needed or not. This reinforces the preference for composition over inheritance.
To achieve this kind of behaviour with inheritance needs polymorphism, and you'd have to use pointers/references everytime you need to work with an object.
Extended functionality could also be different in the future (derived
classes are extended in accordance with the kind of problem being
solved),
In the future, could there be further derivation for the derived ? If yes, how would this further derivation relate to the extension ? If you'd say that further derivation would be independent of the extension, then composition should definitively be the choice.
Now which one of 2 and 3 to prefer ?
Looking at all the arguments above, the third option could be very interesting for both your current needs for a common extension, but also future needs.
Here is the general idea:
class Base {
...
protected:
Extension *ex;
void setExtension(Extension *e); // to be called by ctor or the derived.
public:
bool isExtended() { return ex!=nullptr; }
int getExProperty1(){ if (isExtend()) return ex->getProperty1();} // common member functions
};
But for this to remain extensible for future evolutions, Extension should define its member functions virtual. Then later some derived class could use a derivation of Extension:
class MyDerivedExtension : public Extension { // specially for Derived1 extensions
protected:
string myspecificproperty; // specific for Derived1
public:
int getPropery1 () { /* calculate it differently than for basic Extension */ }
string getProperty2 () { /*...*/ } // specific to Derived1
};
class Derived1: public Base
{
...
protected:
void setExtension(MyDerivedExtension *e) { Base::setExtension(e); } // to be called by ctor.
public:
string getExProperty2(){ if (isExtend()) return ex->getProperty2();} // non common member
};
Found related questions but not the exact variant so I am posting a very simple question.
A derived class inherits from a templated base, and I want to call the base function, how to do it?
template <class A>
class testBase {
public:
void insert(const A& insertType) {
// whatever
}
};
class testDerived : testBase<double> {
// whatever
};
int main() {
testDerived B;
// Compiler doesn't recognize base class insert
// How do you do this?
B.insert(1.0);
}
Need public inheritance (default is private for class):
class testDerived : public testBase<double> {
A class has a default access level of 'private'. You basically inherited 'testBase' using private inheritance so that testBase's public interface is not part of testDerived's. Simple solution:
class testDerived: public testBase<double> {...};
I do wish C++ applied public inheritance by default though since that's generally a much more common case. Then again, we could just all use structs instead. :-D
A common scenario in my code is that I got a functor that is used by many classes in a hierachy.
To make it accessible by all classes and stay DRY, I usually define it as a protected inner struct of my base class like that:
class Base
{
protected:
struct CommonFunctor
{
bool operator()()
{
return true;
}
};
};
class DerivedA : public Base
{
void FooA()
{
bool test = CommonFunctor()();
}
};
class DerivedB : public Base
{
void FooB()
{
bool test = CommonFunctor()();
}
};
I don't like that solution because it clutters my base class with many small functors, that are internal only and even if they are not accessible to the public, they decrease readability of my base class.
Do you know any other solutions for this scenario?
Just implement your functors in new files (BaseClassFunctors.cpp + BaseClassFunctors.h). Put them inside your namespace with an optional subnamespaces (e.g. namespace main.internal).
Now you include the header file in any derived classes you want, without cluttering the base class header.
As much as I (and, apparently, everyone else) hate multiple inheritance, it would come in handy here.
Just create a second class that contains all your functors and in your child classes derived from Base, inherit both Base and this new class.
You can just implement the functor elsewhere and still keep it as a member of the Base:
class Base
{
protected:
struct CommonFunctor;
};
struct Base::CommonFunctor
{
bool operator()()
{
return true;
}
};