Where to define functors used by many derived classes? - c++

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;
}
};

Related

Prevent public uses of a class used as a private base class

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.

Can you force classes inheriting from abstract base class to only have the public methods defined in base case?

Is it possible to have an abstract class but FORCE implementing classes to have only the public methods that are in the abstract class?
I don't care how the private methods work, but I want to force the classes to have only one public method.
For example, say I have the following abstract class:
class MyObjectTransform
{
public:
virtual ~MyObjectTransform()
{
}
virtual MyObject transform(MyObject input) = 0;
};
Then I want to force all objects inheriting from MyObjectTransform to ONLY have a single (other than the constructor) public method, transform. I don't care what private methods the inheriting classes have. Is this possible?
Update:
The goal here is to force the developer to only expose functionality through a single method. For example, consider this situation:
class ATransform
{
private:
MyObject A_Stuff(MyObject input);
public:
override MyObject transform(MyObject input)
{
return this->A_stuff(input);
}
};
class BTransform
{
public:
MyObject B_Stuff(MyObject input);
override MyObject transform(MyObject input)
{
return this->B_stuff(input);
}
};
The problem here is that the dev can call B_Stuffdirectly. I want to prevent this.
No you can't. Derived classes can define any public member functions they want. There is no way to put a constraint on that.
Update:
Declare B_Stuff as private if you don't want that users access it. Declare it as protected if you want that classes derived from BTransform can also use it.
class BTransform
{
private:
MyObject B_Stuff(MyObject input);
Public:
override MyObject transform(MyObject input)
{
return this->B_stuff(input);
}
};
But you can't force with the C++ language to declare B_Stuff as private or protected. It must be defined as a policy.
You are already using the mechanism that is in place for this scenario: it's the abstract base class!
The whole point of it is that all classes in this hierarchy are meant to support being used polymorphically through a pointer/reference to the base class MyObjectTransform. This way the user does not know what public methods the implementing class has because he can only use the one available through the base class: transform.
If you want to enforce this slightly more strictly, don't expose the declaration of the implementing classes in a header at all. Hide BTransform and ATransform, and expose only factory functions along with the abstract base class.
std::unique_ptr<MyObjectTransform> makeATransform()
{
return { new ATransform };
}
std::unique_ptr<MyObjectTransform> makeBTransform()
{
return { new BTransform };
}
This way the client/developer code looks like this:
int main()
{
auto btransform = makeBTransform();
btransform->B_Stuff(input); // ERROR, MyObjectTransform doesn't have this member function.
btransform->transform(input); // FINE
}
Users can only use the one public method in the base class.
Ofcourse someone could cast the pointer to a BTransform*, and then do anything they want (provided they could find out what the actual implementation of BTransform is, since we hid it). But then theres no bypassing the fact that to prevent public methods from being accessible you have to make them private, like chmike wrote. As Herb Sutter said:
C++ protects against Murphy, not Machiavelli
In C++, public functions should be non-virtual and virtual functions should be private (with the exception of the destructor). Applying this guideline makes your problem disappear entirely, because there is only one public function left for clients of the class to call:
class MyObjectTransform
{
public:
virtual ~MyObjectTransform()
{
}
MyObject transform(MyObject input) // non-virtual!
{
// can do extra stuff, e.g. check input for validity
doTransform(input);
}
private:
virtual MyObject doTransform(MyObject input) = 0;
};
class ATransform : public MyObjectTransform
{
private:
MyObject A_Stuff(MyObject input);
MyObject doTransform(MyObject input) override
{
return this->A_Stuff(input);
}
};
class BTransform : public MyObjectTransform
{
private:
MyObject B_Stuff(MyObject input);
MyObject doTransform(MyObject input) override
{
return this->B_Stuff(input);
}
};

C++03: Add fields to several derived classes

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
};

c++ How do you call a templated base-class function from derived class instance

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

How to force all derived classes to implement a virtual method?

Say you have a base class Dep for a tree of classes. There is a virtual method Dep* Dep::create() that I want to be implemented by every single leaf class. Is there any way to enforce this?
Note: The problem here is that there could be intermediate classes (say class B : public A : public Dep) implementing this method (A::create) by accident or because they think they are leaf classes, but are in fact subclassed themselves.
The question ends here.
Context
If you are curious why I need this; I have a class Master which has Dep objects of unknown concrete type. If Master is duplicated, I need to come up with a matching clone of the Dep instance. Next best thing to do is the virtual constructor idiom, which introduces precisely this problem.
Additionally, I cannot even catch this (other then by crashing horribly), because for obscure reasons, people that have more to say than me, have outlawed dynamic_cast in this project (perhaps this is a good decision; But anyways a completely different discussion).
C++ provides no way to keep a class from inheriting from your class, and there is no way to make a particular class in the inheritance hierarchy implement a method. The only rule is that somewhere in the inheritance hierarchy above a particular class (not necessarily in the leaf) all virtual functions must have an implementation for that class to be instantiatable.
For instance, A could inherit from Def and implement all it's [pure] virtual methods. Then if B inherits from A, it doesn't have to implement anything. There's no way to keep that from happening.
So the answer is no, there is no way to enforce this.
Using curiously recurring template fun, you can achieve something quite similar:
template<typename T>
class Cloneable : public T, public Dep
{
private:
Cloneable<T>() : T() { }
public:
static Cloneable<T>* Create() { return new Cloneable<T>(); }
Cloneable<T>* clone() { return new Cloneable<T>(*this); }
};
Instead of deriving from Dep and instantiating via new MyType, use Cloneable<MyType>::Create. Since Cloneable<MyType> is derived from MyType, you can use the instance the same way you would use any MyType, except that it is now guaranteed to have Dep::clone.
Additionally your Master should not accept an instance of type Dep, but enforce that it is a Cloneable<T>. (Replace your orignial function by a simple function template that enforces this.) This guarantees that any Dep inside the master has a correctly implemented clone function.
Since Cloneable<MyType> has no public constructor, it cannot be inherited, however your actual MyType can be further inherited and used just as before.
Did TPTB outlaw all RTTI, or only dynamic_cast<>()? If you can use RTTI, then you can enforce the existence of the method as a postcondition of calling it:
#include <typeinfo>
#include <cassert>
#include <iostream>
#include <stdexcept>
class Base {
protected:
virtual Base* do_create() = 0;
virtual ~Base() {}
public:
Base* create() {
Base *that = this->do_create();
if( typeid(*this) != typeid(*that) ) {
throw(std::logic_error(std::string() +
"Type: " +
typeid(*this).name() +
" != " +
typeid(*that).name()));
}
return that;
}
};
class Derive1 : public Base {
protected:
Base* do_create() { return new Derive1(*this); }
};
class Derive2 : public Derive1 {};
void f(Base*p) { std::cout << typeid(*p).name() << "\n"; }
int main() {
Derive1 d1;
Base *pD1 = d1.create(); // will succeed with correct semantics
Derive2 d2;
Base *pD2 = d2.create(); // will throw exception due to missing Derive2::do_create()
}
If you control the base class AbstractDep then you can enforce that concrete leaf classes must be created by using a class template WithCloning. This leaf can then be sealed so that it cannot be inherited. Or more precisely, instances cannot be created of a derived class.
class AbstractDep
{
template< class Type > friend class WithCloning;
private:
enum FooFoo {};
virtual FooFoo toBeImplementedByLeafClass() = 0;
public:
virtual AbstractDep* clone() const = 0;
};
template< class Type > class WithCloning;
class Sealed
{
template< class Type > friend class WithCloning;
private:
Sealed() {}
};
template< class Type >
class WithCloning
: public Type
, public virtual Sealed
{
private:
AbstractDep::FooFoo toBeImplementedByLeafClass()
{
return AbstractDep::FooFoo();
}
public:
virtual WithCloning* clone() const
{
return new WithCloning( *this );
}
};
typedef WithCloning<AbstractDep> Dep;
class AbstractDerivedDep
: public AbstractDep
{
// AbstractDep::FooFoo toBeImplementedByLeafClass(); // !Not compile.
public:
};
typedef WithCloning<AbstractDerivedDep> DDep;
struct Foo: Dep {}; // !Does not compile if instantiated.
int main()
{
Dep d;
//Foo f;
}
If the classes require more than default construction then that most be solved additionally.
One solution is then to forward an argument pack from the WithCloning constructor (there is an example C++98 implementation on my blog, and C++0x supports that directly).
Summing up, to be instantiable the class must be WithCloning.
Cheers & hth.,
when you say that they are unknown, i presume they still inherit from a common base class /interface right?
only thing i can think of you can use to force is on the virtual base class add
virtual Base* clone() {
assert( 1==0 ); //needs to be overriden
}
so you are forced to override, but this is only detected at run-time when trying to call clone on a instance of a class that is missing the override
even if you are not allowed to use dynamic_cast or RTTI, you can still enable it for debug purposes locally on your build, if that will help you find the typeid of offending classes
it sounds like you are familiar with the clone pattern, but i'll post it quietly in here, and we can forget about it:
http://www.cplusplus.com/forum/articles/18757/