In my application I have to derive some classes from a base one, the problem is that I want to enforce the derived classed to have 3 particular constructor implementation. As c++ don't have virtual pure constructor, it seemed quite desperate (I had to check manually each class implementation to ensure that the particular ctors are implemented, not quite fun to do).
Yesterday I found a crazy way to simulate the comportment of a virtual ctor:
template <class T>
class AbstractEnforcer{
protected:
AbstractEnforcer(){}
private:
static void Enforcer(){
delete new T();
delete new T(*(new unsigned int));
delete new T(*(new unsigned int, *(new QString));
}
}
class AbstractClass : private AbstractEnforcer<AbstractClass>{
}
the only inconvenience with this approach is that I have to to declare all derived class with the syntax:
class X : private AbstractEnforcer<X>
And even if it's not a problem; because the Enforcer() methode never get called (and even so it does nothing [hope so!!!])
My question is:
"is there any mean (not with macros) to force the derived class to use this mechanism without parametrazing the AbstractClass (because this will work in only one level of derivation"
template <class T>
class AbstractClass : private AbstractEnforcer<T>{
}
Your solution does not solve the problem since templated code that isnt used is not instantiated, and thus unless you manually invoke this function - it will not verify the existence of the wanted constructors.
What you can do is have this method called from the constructor of your enforcer:
template <class T>
class AbstractEnforcer{
protected:
AbstractEnforcer(){ Enforcer(); }
private:
static void Enforcer(){
delete new T();
delete new T(*(new unsigned int));
delete new T(*(new unsigned int, *(new QString)));
}
// disable:
AbstractEnforcer (const AbstractEnforcer &enf);
};
class AbstractClass : private AbstractEnforcer<AbstractClass>{
};
int main () {
AbstractClass c;
}
Then, the compiler complains - mission accomplished.
Note that I've disabled the copy constructor so that there will be no way to bypass that check (by calling a different constructor).
Edit - Non leaking Enforcer(): [As there's absolutly no need to use dynamic allocations there..]
static void Enforcer(){
T t1();
T t2(int(3));
T t3(int(4), QString());
}
See this page in the C++ FAQ.
What I would do is something like this:
class AbstractClass {
public:
virtual AbstractClass* create() const = 0;
virtual AbstractClass* create(unsigned int) const = 0;
virtual AbstractClass* create(unsigned int, QString) const = 0;
};
Then each of the derived classes would be forced to override these functions, which should create new objects with different constructors.
From this comment to one of the answers I think that you do not really want to achieve what you are asking here, but rather a different thing. The comment I refer to is:
Part 1:
I knew that we can't have a virtual
constructor and I don't want to have
one, my purpose is to a compiler
static code checking that will alert
me if I forgot to implement a specific
constructor prototype.
Part 2:
My project is a
plugin like dynamic loading system and
I have in some way enforce the ctors
prototypes implementation of the third
party code.
What you are asking in the question is 1, and you can enforce it in different ways, just read some of the answers, or take a look at metaprogramming examples and the boost::type_traits library.
Now, if what you really want is part 2: provide a dynamic loading plugin mechanism then you do not need to enforce the constructors, but a common interface both for the plugin objects and the creation of the plugin objects. There is no way of instantiating an instance of an object of unknown (at compile time) object, and that means that you will not be able to call the constructors from your code. I would suggest
// Interface:
class plugin {
public:
virtual void operation() = 0;
};
class plugin_factory {
public:
virtual plugin* create() = 0;
virtual plugin* create( unsigned int ) = 0;
virtual plugin* create( unsigned int, QString const & ) = 0;
};
Users will need to provide the implementation of a plugin and the factory that creates them. They will probably need to implement a point of entry for their library so that you can get access to the factory (or so they can register their factory within your system, or else I would suggest using a library for these purposes (boost::extension seems like a place to look at)
I'd probably just have a template for generating a test:
template <typename T>
void enforceConstructors() {
T t1;
T t2(0);
QString q;
T t3(0, q);
}
Then somewhere in your tests, do:
enforceConstructors<X>();
enforceConstructors<Y>();
enforceConstructors<Z>();
Those might be all together, or in separate places for each of the classes X, Y, Z. Depends how you want to organise your tests.
If the values I used aren't suitable, either put in some values which are, or else compile that test but don't run it. If you don't have unit tests either get some, or else add the following to the class (instead of inheriting from the base class):
#ifndef NDEBUG
static void test() { enforceConstructors<X>(); }
#endif
You don't usually need to make constructors part of an interface defined by an abstract base class. The reason is that such interfaces are for dynamic polymorphism - you pass an object to some function, and it calls functions on it. You can't "pass" a class to a function and have it instantiate the class other than with templates. Templates mostly enforce their interfaces at compile time anyway - if you instantiate the template and it uses the constructor, then the constructor has to be there.
If you forget to implement the constructor but use it in your code, you will get a compilation error. For example:
Base * p = new Derived( 42 );
will be a compile-time error if the Derived(int) constructor is not provided - the Base constructor will not be used.
I finally adopted this solution, but not quit convienced:
#ifdef NDEBUG
#ifndef ENFORCE_CTORS
#define ENFORCE_CTORS(enforcingTemplate, enforcedClass) \
friend void enforcingCtors(){static enforcingTemplate<enforcedClass> _enforcer;}
#endif
template<class T>
class AbstractEnforcer : T{
public:
explicit AbstractEnforcer(){
T enforcedCtor0( );
T enforcedCtor1( *(new unsigned int) );
T enforcedCtor2( *(new unsigned int), *(new QString) );
T enforcedCtor3( *(new unsigned int), *(new float ) );
}
};
#endif
and in each class that I wan't to enforce I just add like this:
class X{
ENFORCE_CTORS(AbstractEnforcer, X);
/*
.....
*/
}
I didn't find any other way to inject this code dynamically in a class. And I may been unclear about the final purpose of the operation (sorry for my terrible English).
Related
Consider the following abstract class, which will be the interface for a class that writes the information carried by some object to standard output.
class FileBuilder
{
public:
virtual void build(const Object& object) = 0;
virtual ~FileBuilder() = default;
};
At this point I will note that Object is also an abstract class with derived class SpecialObject. Now I am going to implement SpecialFileBuilder : FileBuilder, as follows.
class SpecialFileBuilder : public FileBuilder
{
public:
void build(const SpecialObject& specialObject);
};
...
void SpecialFileBuilder::build(const SpecialObject& specialObject)
{
// Do some stuff
}
I don't fully understand why this should not be possible. SpecialFileBuilder respects the interface FileBuilder, and everywhere which expects a FileBuilder can instead be given a SpecialFileBuilder. I appreciate your help in advance.
Of course, this would work if I changed things to the following.
void SpecialFileBuilder::build(const Object& object)
However, in my implementation of SpecialFileBuilder::build() I need to use the fact that the argument is a SpecialObject, not just an Object.
How should I instead approach this design?
TL;DR no, this does not make any sense.
Full version below.
I don't fully understand why this should not be possible.
virtual void build(const Object& object) = 0;
This declaration is a promise. It promises that build can accept any Object as an argument. Such promises are legally binding for derived classes, i.e. they must implement the promise as stated by the base class. Note the declaration does not promise that build can accept some objects and not others.
FileBuilder* builder = GetBuilder(); // we don't know what kind of builder it is
SpecialObject some;
builder->build(some); // must work
OtherSpecialObject some;
builder->build(other); // must work too
UnrelatedObject whatever;
builder->build(whatever); // must work as well
Now looking at the other declaration
void build(const SpecialObject& specialObject);
It reneges on the promise. The original promise is strong. Give me any object, I can deal with it. The new promise is weak. Oh, I am a special little builder, I can only cope with special little objects!
Sorry bud, you cannot override a strong promise with a weaker one. If you were allowed to, how would we be able to trust any promise?
Now if your design doesn't fit in this outline, i.e. you always know what kind of builder you get, and you don't want to promise to cope with all kinds of objects, then you have selected a wrong tool for the job. Perhaps you want to give generic programming a try.
template <typename T>
class FileBuilder {
virtual void build (const T& t) = 0;
};
class SpecialBuilder: public FileBuilder<SpecialObject> {
void build (const SpecialObject& t) override;
};
Now the code above won't work, we need to fix it
FileBuilder<SpecialObject>* builder = GetBuilder<SpecialObject>(); // we know exactly what we want to build
SpecialObject some;
builder->build(some); // will work;
OtherSpecialObject other;
builder->build(other); // sorry that's not in the contract, won't compile
I don't fully understand why this should not be possible. SpecialFileBuilder respects the interface FileBuilder, and everywhere which expects a FileBuilder can instead be given a SpecialFileBuilder
You may have covariant return type.
But for argument, you would need contra-variant return type (which is not supported in C++).
As following code should be correct
SpecialFileBuilder specialFileBuilder;
FileBuilder& fileBuilder;
SpecialObject2 specialObject2; // Other derived class, unrelated to SpecialObject
Object& object = specialObject2;
fileBuilder.build(object); // correct type
// but
specialFileBuilder.build(specialObject2); // won't compile
contra-variant parameter would be
struct Base {
virtual void f(const Cat&) = 0;
};
struct Derived : Base
{
void f(const Animal&) override; // if contra-variance was supported
};
I came across an open source C++ code and I got curious, why do people design the classes this way?
So first things first, here is the Abstract class:
class BaseMapServer
{
public:
virtual ~BaseMapServer(){}
virtual void LoadMapInfoFromFile(const std::string &file_name) = 0;
virtual void LoadMapFromFile(const std::string &map_name) = 0;
virtual void PublishMap() = 0;
virtual void SetMap() = 0;
virtual void ConnectROS() = 0;
};
Nothing special here and having an abstract class can have several well understood reasons. So from this point, I thought maybe author wanted to share common features among other classes. So here is the next class, which is a seperate class but actually holds a pointer of type abstract class mentioned above (actual cpp file, other two classes are header files) :
class MapFactory
{
BaseMapServer *CreateMap(
const std::string &map_type,
rclcpp::Node::SharedPtr node, const std::string &file_name)
{
if (map_type == "occupancy") return new OccGridServer(node, file_name);
else
{
RCLCPP_ERROR(node->get_logger(), "map_factory.cpp 15: Cannot load map %s of type %s", file_name.c_str(), map_type.c_str());
throw std::runtime_error("Map type not supported")
}
}
};
And now the interesting thing comes, here is the child class of the abstract class:
class OccGridServer : public BaseMapServer
{
public:
explicit OccGridServer(rclcpp::Node::SharedPtr node) : node_(node) {}
OccGridServer(rclcpp::Node::SharedPtr node, std::string file_name);
OccGridServer(){}
~OccGridServer(){}
virtual void LoadMapInfoFromFile(const std::string &file_name);
virtual void LoadMapFromFile(const std::string &map_name);
virtual void PublishMap();
virtual void SetMap();
virtual void ConnectROS();
protected:
enum MapMode { TRINARY, SCALE, RAW };
// Info got from the YAML file
double origin_[3];
int negate_;
double occ_th_;
double free_th_;
double res_;
MapMode mode_ = TRINARY;
std::string frame_id_ = "map";
std::string map_name_;
// In order to do ROS2 stuff like creating a service we need a node:
rclcpp::Node::SharedPtr node_;
// A service to provide the occupancy grid map and the message with response:
rclcpp::Service<nav_msgs::srv::GetMap>::SharedPtr occ_service_;
nav_msgs::msg::OccupancyGrid map_msg_;
// Publish map periodically for the ROS1 via bridge:
rclcpp::TimerBase::SharedPtr timer_;
};
So what is the purpose of the MapFactory class?
To be more specific - what is the advantage of creating a class which holds a pointer of type Abstract class BaseMapServer which is a constructor (I believe) and this weird constructor creates a memory for the new object called OccGridServer and returns it? I got so confused by only writing this. I really want to become a better C++ coder and I am desperate to know the secret behind these code designs.
The MapFactory class is used to create the correct subclass instance of BaseMapServer based on the parameters passed to it.
In this particular case there is only one child class instance, but perhaps there are plans to add more. Then when more are added the factory method can look something like this:
BaseMapServer *CreateMap(
const std::string &map_type,
rclcpp::Node::SharedPtr node, const std::string &file_name)
{
if (map_type == "occupancy") return new OccGridServer(node, file_name);
// create Type2Server
else if (map_type == "type2") return new Type2Server(node, file_name);
// create Type3Server
else if (map_type == "type3") return new Type3Server(node, file_name);
else
{
RCLCPP_ERROR(node->get_logger(),
"map_factory.cpp 15: Cannot load map %s of type %s",
file_name.c_str(), map_type.c_str());
throw std::runtime_error("Map type not supported")
}
}
This has the advantage that the caller doesn't need to know the exact subclass being used, and in fact the underlying subclass could potentially change or even be replaced under the hood without the calling code needing to be modified. The factory method internalizes this logic for you.
Its a Factory pattern. See https://en.wikipedia.org/wiki/Factory_method_pattern. It looks like the current code only supports one implementation (OccGridServer), but more could be added at a future date. Conversely, if there's only ever likely to be one concrete implementation, then it's overdesign.
This is example of the factory design pattern. The use case is this: there are several types of very similar classes that will be used in code. In this case, OccGridServer is the only one actually shown, but a generic explanation might reference hypothetical Dog, Cat, Otter, etc. classes. Because of their similarity, some polymorphism is desired: if they all inherit from a base class Animal they can share virtual class methods like ::genus, ::species, etc., and the derived classes can be pointed to or referred to with base class pointers/references. In your case, OccGridServer inherits from BaseMapServer; presumably there are other derived classes as well, and pointers/references.
If you know which derived class is needed at compile time, you would normally just call its constructor. The point of the factory design pattern is to simplify selection of a derived class when the particular derived class is not known until runtime. Imagine that a user picks their favorite animal by selecting a button or typing in a name. This generally means that somewhere there's a big if/else block that maps from some type of I/O disambiguator (string, enum, etc.) to a particular derived class type, calling its constructor. It's useful to encapsulate this in a factory pattern, which can act like a named constructor that takes this disambiguator as a "constructor" parameter and finds the correct derived class to construct.
Typically, by the way, CreateMap would be a static method of BaseMapServer. I don't see why a separate class for the factory function is needed in this case.
I'm developing a class for my AVR cpu.
The class is going to handle all port related operations like Set, Read, etc;
Constructor looks like:
(...)
public:
Port(volatile uint8_t * DDR, volatile uint8_t * PORT);
(...)
And it is constructed at the beginning of the main():
int main()
{
Port PortA(&DDRA, &PORTA);
(...)
}
Now I want to make sure that nowhere else in the program object with same parameters would be constructed. It is sure that I cannot create array or map to find it out and throw an exception. It must be done at compile time. So basicly I want to force avr-g++ to check if any other Port(the same first parameter OR the same second parameter) exists in current project.
All functions uses pointers / references to Port objects.
How about the following?
The address of the pointers has to be known at compile-time.
template<int *p>
class Tester
{
public:
static Tester& GetInstance()
{
static Tester t;
return t;
}
private:
Tester() {}
};
int i;
int main()
{
Tester<&i>& t = Tester<&i>::GetInstance();
}
If you only want one instance of a class, then why use classes? The whole purpose of classes, is that you can have multiple intances. Just stick to global variables and free functions.
This is not pretty, but it does get the job done. 10 years experience says embedded work tends to be like this at times. :/
I tested this with a simple class under MSVC, you'll have to adapt for your needs, but it does demonstrate the principle.
Declare your class like this in the header:
class t
{
public:
#ifdef ALLOW_CTOR
t(int i);
~t();
#endif
int get();
private:
int m_i;
};
Then in exactly one file add the line:
#define ALLOW_CTOR 1
include the header file, declare your port instances as file scope variables, and then implement all the class methods of your class, ctor, dtor, accessors, etc.
If you do not place ALLOW_CTOR line in other source files, they can still use the accessor methods in your class, but they can't use the constructor. In the absence of the correct constructor, MSVC complains because it tries to use the default copy constructor, but since the parameter lists don't match, it fails. I suspect the compiler you're using will fail in some way, I'm just not sure exactly what the failure will be.
#Neil Kirk
If failure to provide a declaration of a ctor at all for a compilation unit leads to undefined behavior, then there are ways to solve that.
class t
{
#ifdef ALLOW_CTOR
public:
#else
private:
#endif
t(int i);
public:
~t();
int get();
private:
int m_i;
};
marks the ctor as public in one, but private in all other compilation units, leading to a well defined error: the inability to access a private member function.
I have a template class that get two template arguments.
template <class T,class A>
class Z{...};
Say I have four types of T, and same amount for A. So, there are 16 options!
If I want to choose one of them at runtime, I need to write a huge and disgusting case.
I know that C++ doesn't support runtime templates.
Is there another way to do it?
A way to achieve something kind of similar is to add dependencies to class Z and provide these at runtime -- which is known as the Strategy pattern.
Of course this means that class Z is no longer templated with all that this entails. But there's really no way to have your pie and eat it too: templates are a compile-time construct, while you are asking about ways to configure something at runtime. You cannot configure a type at runtime, only an object.
No, there really isn't. It's inherent in the nature of templates that this is completely and totally impossible.
I'm not saying that this is a good solution but I've seen it implemented in the past: you could keep the code for your templated class around in a resource file and compile it at runtime into a pluggable module!
By the way, I would suggest to refactor the problem so that instead of instantiating MN templates you only need M + N; I don't know it this is possible in your problem but it usually is, e.g. if you are translating from a type to another, it's usually possible to introduce an intermediate representation that works for all types. You still need either a case or a form of polymorphism to handle the various type though, but that's kind of inevitable.
Virtual Classes gives you at runtime what templates give you at compile time .. kind of.
Template code when written is not real code, just a template that can be used to generate code. Every time you use it .. it'll usually generate the code right there. eg.
Z<int, std::string> z; // At this point a new class called Z<int, std::string> is defined, then the code to instantiate it at run time is generated.
This might be a useful read: c++ standard practice: virtual interface classes vs. templates
Maybe this is what you're after ? The similar sort of thing using polymorphism and virtual classes ..
class Z{
public:
virtual void doSomething();
};
class ZT : public Z {
public:
void doSomething();
};
class ZA : public Z {
public:
void doSomething();
};
...
void useClasses(Z* ptr) {
ZT* ztPtr = dynamic_cast<ZT*>(ptr); // Runtime conversion
if (ztPtr) {
// do specific stuff for this type
} else {
ptr->doSomething(); // generic behaviour that'll call whichever class ptr actually is
}
}
This may or may not fit your needs, but a simple common interface sounds like what you want:
class Z_interface{ //abstract interface
public:
virtual ~Z_interface() {} //virtual destructor
virtual void func()=0; //virtual member
};
template <class T,class A>
class Z : public Z_interface { //implimentation
public:
virtual ~Z_interface() {}
virtual void func() {}
};
int main() {
std::unique_ptr<Z_interface> ptr;
switch(stuff) { //make the correct type
case 0: ptr = std::unique_ptr<Z_interface>(new Z<int, char>()); break;
case 1: ptr = std::unique_ptr<Z_interface>(new Z<int, short>()); break;
case 2: ptr = std::unique_ptr<Z_interface>(new Z<long, char>()); break;
case 3: ptr = std::unique_ptr<Z_interface>(new Z<long, short>()); break;
};
ptr->func(); //don't care about the type anymore, just the algorithms
}
Inside of a static member function I need to get the type.
class MyClass
{
public:
static void myStaticFunc();
...
};
And then in the implementation I want to have:
void MyClass::myStaticFunc()
{
// Get MyClass as a type so I can cast using it
(get_type_from_static_function()*)someOtherVariable;
}
Is this even possible? Normally I would use something from typeinfo on an object but I don't have this to work with.
I do not want to just use (MyClass*) because this is going inside of a macro and I'd like to keep it as simple as possible so that it can be called without a class name.
If it helps I am using QT but I couldn't find any macros to get the current class. It doesn't necessarily need to be programmatic - it can be a macro.
Cheers!
EDIT:
Here is the actual macro function:
#define RPC_FUNCTION(funcName) \
static void rpc_##funcName(void* oOwner, RpcManager::RpcParamsContainer params){ ((__class__*)oOwner)->funcName(params); }; \
void funcName(RpcManager::RpcParamsContainer params);
I then call RPC_FUNCTION(foo) in a class declaration. I want __class__ to be whatever class declaration I am in. I'm well aware I can just add className after funcName but I want to keep this as simple as possible when actually using it. My RPC manager calls rpc_foo and passes a pointer to an object of the class I declared it in. Essentially I need to know how to determine the actual class of that void* parameter.
In Visual Studio 2012 you can use that trick, but it will not work in gcc, at least for now.
template<typename base_t>
static auto GetFunctionBaseType(void(base_t::*)())->base_t;
struct TBase
{
template<typename T> void GetBaseType();
typedef decltype(GetFunctionBaseType(&GetBaseType<void>)) this_t;
static void rpc_func1(void * ptr)
{
((this_t*)ptr)->func1();
}
};
I believe that what you're asking for at heart is simply not possible: C++ is a statically typed language, which means that all type information must be available at compile time (runtime polymorphism notwithstanding). That is, when you say,
T x;
then the type T must be known at compile time. There is no such thing as "T_from_user() x;", whereby the actual type of a variable is determined at runtime. The language just isn't designed that way.
Usually if you're asking such a question that's an indicator that you're going about a problem the wrong way, though. Typical solutions for polymorphic situations involve class inheritance and virtual functions, or other sorts of lookup tables, or really any number of different approaches. Your request for a preprocessor macro also indicates that something is off. Any programming language has its idioms, and veering too far from those is usually a bad idea.
What you want to do is called Reflection. It was implemented in .NET (I don't know, maybe in Java too) and is going to be implemented in future standards of C++.
It seems you have a few unrelated classes that have a number of methods in common (the ones that can be sent as the funcName argument in your example).
Instead of having these unrelated classes, consider a polymorphic approach. For example, let's say the functions that you support are func1 and func2, then you can work this out in this way:
class BaseClass {
public:
virtual void func1(RpcManager::RpcParamsContainer args) = 0;
virtual void func2(RpcManager::RpcParamsContainer args) = 0;
};
class MyClass1 : public BaseClass {
public:
virtual void func1(RpcManager::RpcParamsContainer args) { /* func1 implementation here */ }
virtual void func2(RpcManager::RpcParamsContainer args) { /* func2 implementation here */ }
};
class MyClass2 : public BaseClass {
public:
virtual void func1(RpcManager::RpcParamsContainer args) { /* func1 implementation here */ }
virtual void func2(RpcManager::RpcParamsContainer args) { /* func2 implementation here */ }
};
With the above design your can pass a BaseClass* around, and you can call func1 or func2 without having to do any casts, and the compiler will find the correct version to invoke. For example, in your macro you could do something like this:
#define RPC_FUNCTION(funcName) static void rpc_##funcName(BaseClass* oOwner, RpcManager::RpcParamsContainer params){ oOwner->funcName(params); };
I hope this helps!
Are searching for the function macro? It's a macro that expands to the current function name.
__FUNCTION__
No, a static method can only see static members of the class. It doesn't make sense for it to access instance members (as in, standard variables etc) as they don't exist unless the class has been instantiated.
It seems like you want something like the Singleton design pattern. This allows for only a single instance of the class to exist at a time.
Another way would be to have a static list of all instances of a class, then in the class constructor, add the this pointer to that list. As I say though, static members cannot access instance variables, as they may not exist at all.
I suppose the greater question is this: why do you need to access an instance variable from a static member? If you require access to an instance member, you should be calling the function in the context of the current instance, otherwise you're breaking the OOP paradigm pretty hard.