C++ Passing a class as a parameter - c++

I'm wondering if it's possible to pass a class as a parameter in c++.
Not passing a Class Object, but the class itself which would allow me to use this class like this.
void MyFunction(ClassParam mClass)
{
mClass *tmp = new mClass();
}
The above is not real code, but it hopefully explains what I'm trying to do in an example.

You can use templates to accomplish something similar (but not exactly that):
template<class T>
void MyFunction()
{
T *tmp = new T();
}
and call it with MyFunction<MyClassName>().
Note that this way, you can't use a "variable" in place of T. It should be known at compile time.

C++ does not store meta data about classes as other languages do. Assuming that you always use a class with a parameterless constructor, you can use templates to achieve the same thing:
template <typename T>
void MyFunction()
{
T* p = new T;
}

You could also pass in a function pointer that when called creates an instance of whatever you want and returns that.
void MyFunction(ClassCreatorPtr makeClassFn)
{
void * myObject = makeClassFn();
}
You'd need to have it return a pointer to a base class to do anything really interesting with it.

You are looking for templates

An alternative to templates is to use a lambda closure with C++11. Here's my preference.
// in header file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator);
// in source file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator) {
// Some processing. Perhaps the interface_params are generated
// inside this function instead of being passed to it.
IClass * mCls = cls_allocator(interface_params);
// Do whatever with mCls
return mCls;
}
// Somewhere else in the code.
{
Param1Type param1 = whatever1;
Param2Type param1 = whatever2;
// param1, param2, etc. are parameters that only
// SomeClsDerivedFromIClass constructor knows about. The syntax &param1
// achieves the closure.
// interface_param1 is common to all classes derived from IClass.
// Could more than one parameter. These parameters are parameters that
// vary from different calls of MyFunctionThatDoesStuff in different
// places.
auto cls_allocator =
[&param1, &param2](const IParams & interface_params)->IClass * {
return new SomeCls1DerivedFromIClass(interface_params,
param1, param2);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
// Somewhere else in the code again.
{
ParamXType paramX = whateverX;
ParamYType paramY = whateverY;
auto cls_allocator =
[&paramX, &paramY](const IParams & interface_params)->IClass * {
return new SomeCls2DerivedFromIClass(interface_params,
paramX, paramY);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
The above code idea works well for a quick builder pattern or some factory pattern variation. The lambda is basically a factory method. To make it even more dynamic you can use auto for parameter typing. Something like this.
auto * MyFunctionThatDoesStuff(const auto & interface_params,
std::function<auto * (const auto & interface_params)> cls_allocator);
I'm coming at this from Python influence where you can just pass the class type to the function.

You can create a static factory method on your class(es) that simply returns a new instance of the class and then you can pass around pointers to that function similarly to what you want to do in your example. Return types are covariant, so if all your classes implement the same interface, you can have the function pointer return that interface. If they don't all have a common interface, you'll probably be left with returning void *. Either way, if you need to use the specific subclass, you'll have to dynamic_cast.

Related

C++ Gmock - test function which uses shared_ptr <FactoryClass>

I am new to gtest/gmock and trying to test a simple function in c++ which has a two pointers 'm_propBsh_p' and 'm_eBsh_p'; these pointers becomes valid after some factory-creations, however i do not want to get involve in factory classes complexities and callbacks.
Following is the function definition that i want to write test for:
std::string Foo::toString(const std::string &indent) const
{
....
std::string str =
(m_propBsh_p != nullptr) ? m_propBsh_p -> toString("P-BSH: ") : "-";
str +=
(m_eBsh_p != nullptr) ? m_eBsh_p -> toString("E-BSH: ") : "-";
return str;
}
Since I am just interested in testing this particular toString function therefore I just want to have valid pointers for 'm_propBsh_p' and 'm_eBsh_p'. I am aiming/trying for something like following:
//Assuming to have mocked class for pointers
std::shared_ptr<MockedBshClass> m_mockEBsh_p;
std::shared_ptr<MockedBshClass> m_mockPropBsh_p;
TEST_F(FooTest, toStringBshInfoPass)
{
std::string eBshAndpBshStr = "eBshAndpBshStr";
ON_CALL(*m_mockPropBsh_p, toString(_)).WillByDefault(Return(eBshAndpBshStr));
ON_CALL(*m_mockEBsh_p, toString(_)).WillByDefault(Return(eBshAndpBshStr ));
//EXPECT_CALL((*m_mockPropBsh_p), toString(_)).Times(1);
//EXPECT_CALL((*m_mockEBsh_p), toString(_)).Times(1);
//Call mock or some fake function which makes m_propBsh_p & m_eBsh_p valid.
foo->makePtrValidAgain(); //however this is a complex function which bring more callbacks and complexity and i do not want to call, instead i want to have some fake/mocked function which just gives me valid pointers
EXPECT_THAT(foo->toString(""),HasSubstr(eBshAndpBshStr+eBshAndpBshStr));
}
Following is bit background of the Foo class and pointers:
Class Foo : fooParent..
{
...
void makePtrValidAgain();
std::string toString();
..
typedef std::shared_ptr<BshClass> m_propBsh_p;
typedef std::shared_ptr<BshClass> m_eBsh_p;
...
};
void Foo::makePtrValidAgain()
{
...
auto someFactory = m_dependencyContainer->get<bssh::SomeFactory>();
assert(someFactory);
auto nextTask = [this](std::uint32_t dummy){runAfterFoo();};
m_propBsh_p = someFactory->create(callback, nextTask);
m_propBsh_p->execute();
...
//and same happens with m_eBsh_p
return;
}
I am not sure, what is a best way to avoid complexity for test of such simple function using gmock/gtest, purpose for me is to have valid pointers as mentioned above.
First of all, it seems your ON_CALLs are incorrect. You mock the BshClass, so you want to create expectations on methods of BshClass (and toString() isn't one). You should mock for example
ON_CALL(*m_mockEBsh_p, execute())/*stuff to do*/;
To answer your question:
If the factory is used in Foo constructor already (you passed your mock pointers to m_propBsh_p and m_eBsh_p), then you could just use std::shared_ptr functionality to control if they point to something or not (e.g. via reset()).
Otherwise, it seems a good idea to extract factory method from makePtrValidAgain() - this function already has more than one responsibility, it creates pointers and calls methods on them.
I'd propose something like:
Class Foo : fooParent..
{
...
void makePtrValidAgain();
std::string toString();
..
private:
void resetPointers();
typedef std::shared_ptr<BshClass> m_propBsh_p;
typedef std::shared_ptr<BshClass> m_eBsh_p;
...
};
void Foo::makePtrValidAgain()
{
...
resetPointers(); //if needed
m_propBsh_p->execute();
...
//and same happens with m_eBsh_p
}
void resetPointers()
{
auto someFactory = m_dependencyContainer->get<bssh::SomeFactory>();
assert(someFactory);
auto nextTask = [this](std::uint32_t dummy){runAfterFoo();};
m_propBsh_p = someFactory->create(callback, nextTask);
//also with the other pointer
//or better pass the pointer to reset as argument if possible
}
and call resetPointers() in Foo constructor if possible. Or make it public and call it from UT. This way the problem falls down to first option with m_propBsh_p and m_eBsh_p being set and you have access to them from UT via your mock pointers.

Accessing derived members from a container of base pointers

Consider the following code:
struct Object
{
bool hasComponent(std::string sComponentID);
Component& getComponent(std::string sComponentID);
std::vector<Component*> vComponents;
}
struct System
{
std::vector<Object*> vObjects;
}
My system will iterate over each Object in its vector and need to access data from derived members of Component (they all contain different state and data for the system to use).
I've considered something like this:
struct NetworkComponent : Component
{
std::string sID;
NetworkComponent(std::string tempID) : sID(tempID) {};
//Network data here
}
for(Object* p : vObjects)
{
if(p->hasComponent("network")
{
NetworkComponent& network = static_cast<NetworkComponent&>(p->getComponent("network");
//Access the data in the structure and do stuff with it.
}
}
This does however feel VERY "hacky"; not to mention unsafe.
I was wondering if there is a better way to do things like this, or at the very least how to avoid this problem in the future?
Are there any good articles written on this subject that I can look up?
EDIT: dynamic_cast is NOT an option due to how slow it is.
It sounds like you are trying to reinvent dynamic_cast
I'd refactor the getComponent method to return a pointer (a nullptr if no such component exists) instead of a reference and also pass the string argument with a constant reference:
Component * getComponent(const std::string & sComponentId);
Then you can do something like this:
template <typename CompType, typename ... Args>
CompType * getComponentOfType(Args && ... args)
{ return dynamic_cast<CompType *>(getComponent(std::forward<Args>(args)...)); }
If dynamic_cast is not an option here, use static_cast. By doing this you only lose a layer of safety for programming errors in this case.
And do something like:
for(Object * const p : vObjects) {
assert(p);
NetworkComponent * const net =
p->getComponentOfType<NetworkComponent>("network");
if (net) {
// Use the network component.
}
}
You can define class Object to contain virtual methods, which you want to have in derived classes.
Each of them should throw an exception, which mean this object didn't redefined this method.
Of course, in each of derived classes you should redefine methods that it's objects should have.

Design Pattern for caching different derived types without using RTTI

Let's say I have a family of classes which all implement the same interface, perhaps for scheduling:
class Foo : public IScheduler {
public:
Foo (Descriptor d) : IScheduler (d) {}
/* methods */
};
class Bar : public IScheduler {
public:
Bar (Descriptor d) : IScheduler (d) {}
/* methods */
};
Now let's say I have a Scheduler class, which you can ask for an IScheduler-derived class to be started for a given descriptor. If it already exists, you'll be given a reference to it. If one doesn't exist, then it creates a new one.
One hypothetical invocation would be something like:
Foo & foo = scheduler->findOrCreate<Foo>(descriptor);
Implementing that would require a map whose keys were (descriptor, RTTI) mapped to base class pointers. Then you'd have to dynamic_cast. Something along these lines, I guess:
template<class ItemType>
ItemType & Scheduler::findOrCreate(Descriptor d)
{
auto it = _map.find(SchedulerKey (d, typeid(ItemType)));
if (it == _map.end()) {
ItemType * newItem = new ItemType (d);
_map[SchedulerKey (d, typeid(ItemType))] = newItem;
return *newItem;
}
ItemType * existingItem = dynamic_cast<ItemType>(it->second);
assert(existingItem != nullptr);
return *existingItem;
}
Wondering if anyone has a way to achieve a similar result without leaning on RTTI like this. Perhaps a way that each scheduled item type could have its own map instance? A design pattern, or... ?
The address of a function, or class static member, is guaranteed to be unique (as far as < can see), so you could use such an address as key.
template <typename T>
struct Id { static void Addressed(); };
template <typename ItemType>
ItemType const& Scheduler::Get(Descriptor d) {
using Identifier = std::pair<Descriptor, void(*)()>;
Identifier const key = std::make_pair(d, &Id<ItemType>::Addressed);
IScheduler*& s = _map[key];
if (s == nullptr) { s = new ItemType{d}; }
return static_cast<ItemType&>(*s);
}
Note the use of operator[] to avoid a double look-up and simplify the function body.
Here's one way.
Add a pure virtual method to IScheduler:
virtual const char *getId() const =0;
Then put every subclass to it's own .h or .cpp file, and define the function:
virtual const char *getId() const { return __FILE__; }
Additionally, for use from templates where you do have the exact type at compile time, in the same file define static method you can use without having class instance (AKA static polymorphism):
static const char *staticId() { return __FILE__; }
Then use this as cache map key. __FILE__ is in the C++ standard, so this is portable too.
Important note: use proper string compare instead of just comparing pointers. Perhaps return std::string instead of char* to avoid accidents. On the plus side, you can then compare with any string values, save them to file etc, you don't have to use only values returned by these methods.
If you want to compare pointers (like for efficiency), you need a bit more code to ensure you have exactly one pointer value per class (add private static member variable declaration in .h and definition+initialization with FILE in corresponding .cpp, and then return that), and only use the values returned by these methods.
Note about class hierarchy, if you have something like
A inherits IScheduler, must override getId()
A2 inherits A, compiler does not complain about forgetting getId()
Then if you want to make sure you don't accidentally forget to override getId(), you should instead have
abstract Abase inherits IScheduler, without defining getId()
final A inherits Abase, and must add getId()
final A2 inherits Abase, and must add getId(), in addition to changes to A
(Note: final keyword identifier with special meaning is C++11 feature, for earlier versions just leave it out...)
If Scheduler is a singleton this would work.
template<typename T>
T& Scheduler::findOrCreate(Descriptor d) {
static map<Descriptor, unique_ptr<T>> m;
auto& p = m[d];
if (!p) p = make_unique<T>(d);
return *p;
}
If Scheduler is not a singleton you could have a central registry using the same technique but mapping a Scheduler* / Descriptor pair to the unique_ptr.
If you know all your different subtypes of IsScheduler, then yes absolutely. Check out Boost.Fusion, it let's you create a map whose key is really a type. Thus for your example, we might do something like:
typedef boost::fusion::map<
boost::fusion::pair<Foo, std::map<Descriptor, Foo*>>,
boost::fusion::pair<Bar, std::map<Descriptor, Bar*>>,
....
> FullMap;
FullMap map_;
And we will use that map thuslly:
template <class ItemType>
ItemType& Scheduler::findOrCreate(Descriptor d)
{
// first, we get the map based on ItemType
std::map<Descriptor, ItemType*>& itemMap = boost::fusion::at_key<ItemType>(map_);
// then, we look it up in there as normal
ItemType*& item = itemMap[d];
if (!item) item = new ItemType(d);
return item;
}
If you try to findOrCreate an item that you didn't define in your FullMap, then at_key will fail to compile. So if you need something truly dynamic where you can ad hoc add new schedulers, this won't work. But if that's not a requirement, this works great.
static_cast the ItemType* to void* and store that in the map.
Then, in findOrCreate, just get the void* and static_cast it back to ItemType*.
static_casting T* -> void* -> T* is guaranteed to get you back the original pointer. You already use typeid(ItemType) as part of your key, so it's guaranteed that the lookup will only succeed if the exact same type is requested. So that should be safe.
If you also need the IScheduler* in the scheduler map just store both pointers.

Factory method anti-if implementation

I'm applying the Factory design pattern in my C++ project, and below you can see how I am doing it. I try to improve my code by following the "anti-if" campaign, thus want to remove the if statements that I am having. Any idea how can I do it?
typedef std::map<std::string, Chip*> ChipList;
Chip* ChipFactory::createChip(const std::string& type) {
MCList::iterator existing = Chips.find(type);
if (existing != Chips.end()) {
return (existing->second);
}
if (type == "R500") {
return Chips[type] = new ChipR500();
}
if (type == "PIC32F42") {
return Chips[type] = new ChipPIC32F42();
}
if (type == "34HC22") {
return Chips[type] = new Chip34HC22();
}
return 0;
}
I would imagine creating a map, with string as the key, and the constructor (or something to create the object). After that, I can just get the constructor from the map using the type (type are strings) and create my object without any if. (I know I'm being a bit paranoid, but I want to know if it can be done or not.)
You are right, you should use a map from key to creation-function.
In your case it would be
typedef Chip* tCreationFunc();
std::map<std::string, tCreationFunc*> microcontrollers;
for each new chip-drived class ChipXXX add a static function:
static Chip* CreateInstance()
{
return new ChipXXX();
}
and also register this function into the map.
Your factory function should be somethink like this:
Chip* ChipFactory::createChip(std::string& type)
{
ChipList::iterator existing = microcontrollers.find(type);
if (existing != microcontrollers.end())
return existing->second();
return NULL;
}
Note that copy constructor is not needed, as in your example.
The point of the factory is not to get rid of the ifs, but to put them in a separate place of your real business logic code and not to pollute it. It is just a separation of concerns.
If you're desperate, you could write a jump table/clone() combo that would do this job with no if statements.
class Factory {
struct ChipFunctorBase {
virtual Chip* Create();
};
template<typename T> struct CreateChipFunctor : ChipFunctorBase {
Chip* Create() { return new T; }
};
std::unordered_map<std::string, std::unique_ptr<ChipFunctorBase>> jumptable;
Factory() {
jumptable["R500"] = new CreateChipFunctor<ChipR500>();
jumptable["PIC32F42"] = new CreateChipFunctor<ChipPIC32F42>();
jumptable["34HC22"] = new CreateChipFunctor<Chip34HC22>();
}
Chip* CreateNewChip(const std::string& type) {
if(jumptable[type].get())
return jumptable[type]->Create();
else
return null;
}
};
However, this kind of approach only becomes valuable when you have large numbers of different Chip types. For just a few, it's more useful just to write a couple of ifs.
Quick note: I've used std::unordered_map and std::unique_ptr, which may not be part of your STL, depending on how new your compiler is. Replace with std::map/boost::unordered_map, and std::/boost::shared_ptr.
No you cannot get rid of the ifs. the createChip method creats a new instance depending on constant (type name )you pass as argument.
but you may optimaze yuor code a little removing those 2 line out of if statment.
microcontrollers[type] = newController;
return microcontrollers[type];
To answer your question: Yes, you should make a factory with a map to functions that construct the objects you want. The objects constructed should supply and register that function with the factory themselves.
There is some reading on the subject in several other SO questions as well, so I'll let you read that instead of explaining it all here.
Generic factory in C++
Is there a way to instantiate objects from a string holding their class name?
You can have ifs in a factory - just don't have them littered throughout your code.
struct Chip{
};
struct ChipR500 : Chip{};
struct PIC32F42 : Chip{};
struct ChipCreator{
virtual Chip *make() = 0;
};
struct ChipR500Creator : ChipCreator{
Chip *make(){return new ChipR500();}
};
struct PIC32F42Creator : ChipCreator{
Chip *make(){return new PIC32F42();}
};
int main(){
ChipR500Creator m; // client code knows only the factory method interface, not the actuall concrete products
Chip *p = m.make();
}
What you are asking for, essentially, is called Virtual Construction, ie the ability the build an object whose type is only known at runtime.
Of course C++ doesn't allow constructors to be virtual, so this requires a bit of trickery. The common OO-approach is to use the Prototype pattern:
class Chip
{
public:
virtual Chip* clone() const = 0;
};
class ChipA: public Chip
{
public:
virtual ChipA* clone() const { return new ChipA(*this); }
};
And then instantiate a map of these prototypes and use it to build your objects (std::map<std::string,Chip*>). Typically, the map is instantiated as a singleton.
The other approach, as has been illustrated so far, is similar and consists in registering directly methods rather than an object. It might or might not be your personal preference, but it's generally slightly faster (not much, you just avoid a virtual dispatch) and the memory is easier to handle (you don't have to do delete on pointers to functions).
What you should pay attention however is the memory management aspect. You don't want to go leaking so make sure to use RAII idioms.

handling pointer to member functions within hierachy in C++

I'm trying to code the following situation:
I have a base class providing a framework for handling events. I'm trying to use an array of pointer-to-member-functions for that. It goes as following:
class EH { // EventHandler
virtual void something(); // just to make sure we get RTTI
public:
typedef void (EH::*func_t)();
protected:
func_t funcs_d[10];
protected:
void register_handler(int event_num, func_t f) {
funcs_d[event_num] = f;
}
public:
void handle_event(int event_num) {
(this->*(funcs_d[event_num]))();
}
};
Then the users are supposed to derive other classes from this one and provide handlers:
class DEH : public EH {
public:
typedef void (DEH::*func_t)();
void handle_event_5();
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
........
}
};
This code wouldn't compile, since DEH::func_t cannot be converted to EH::func_t. It makes perfect sense to me. In my case the conversion is safe since the object under this is really DEH. So I'd like to have something like that:
void EH::DEH_handle_event_5_wrapper() {
DEH *p = dynamic_cast<DEH *>(this);
assert(p != NULL);
p->handle_event_5();
}
and then instead of
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
in DEH::DEH()
put
register_handler(5, &EH::DEH_handle_event_5_wrapper);
So, finally the question (took me long enough...):
Is there a way to create those wrappers (like EH::DEH_handle_event_5_wrapper) automatically?
Or to do something similar?
What other solutions to this situation are out there?
Thanks.
Instead of creating a wrapper for each handler in all derived classes (not even remotely a viable approach, of course), you can simply use static_cast to convert DEH::func_t to EH::func_t. Member pointers are contravariant: they convert naturally down the hierarchy and they can be manually converted up the hierarchy using static_cast (opposite of ordinary object pointers, which are covariant).
The situation you are dealing with is exactly the reason the static_cast functionality was extended to allow member pointer upcasts. Moreover, the non-trivial internal structure of a member function pointer is also implemented that way specifically to handle such situations properly.
So, you can simply do
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, static_cast<EH::func_t>(f5));
........
}
I would say that in this case there's no point in defining a typedef name DEH::func_t - it is pretty useless. If you remove the definition of DEH::func_t the typical registration code will look as follows
DEH() {
func_t f5 = static_cast<func_t>(&DEH::handle_event_5);
// ... where `func_t` is the inherited `EH::func_t`
register_handler(5, f5);
........
}
To make it look more elegant you can provide a wrapper for register_handler in DEH or use some other means (a macro? a template?) to hide the cast.
This method does not provide you with any means to verify the validity of the handler pointer at the moment of the call (as you could do with dynamic_cast in the wrapper-based version). I don't know though how much you care to have this check in place. I would say that in this context it is actually unnecessary and excessive.
Why not just use virtual functions? Something like
class EH {
public:
void handle_event(int event_num) {
// Do any pre-processing...
// Invoke subclass hook
subclass_handle_event( event_num );
// Do any post-processing...
}
private:
virtual void subclass_handle_event( int event_num ) {}
};
class DEH : public EH {
public:
DEH() { }
private:
virtual void subclass_handle_event( int event_num ) {
if ( event_num == 5 ) {
// ...
}
}
};
You really shouldn't be doing it this way. Check out boost::bind
http://www.boost.org/doc/libs/1_43_0/libs/bind/bind.html
Elaboration:
First, I urge you to reconsider your design. Most event handler systems I've seen involve an external registrar object that maintains mappings of events to handler objects. You have the registration embedded in the EventHandler class and are doing the mapping based on function pointers, which is much less desirable. You're running into problems because you're making an end run around the built-in virtual function behavior.
The point of boost::bindand the like is to create objects out of function pointers, allowing you to leverage object oriented language features. So an implementation based on boost::bind with your design as a starting point would look something like this:
struct EventCallback
{
virtual ~EventCallback() { }
virtual void handleEvent() = 0;
};
template <class FuncObj>
struct EventCallbackFuncObj : public IEventCallback
{
EventCallbackT(FuncObj funcObj) :
m_funcObj(funcObj) { }
virtual ~EventCallbackT() { }
virtual void handleEvent()
{
m_funcObj();
}
private:
FuncObj m_funcObj;
};
Then your register_handler function looks something like this:
void register_handler(int event_num, EventCallback* pCallback)
{
m_callbacks[event_num] = pCallback;
}
And your register call would like like:
register_handler(event,
new EventCallbackFuncObj(boost::bind(&DEH::DEH_handle_event_5_wrapper, this)));
Now you can create a callback object from an (object, member function) of any type and save that as the event handler for a given event without writing customized function wrapper objects.