This question already has answers here:
Error logging in c++
(3 answers)
Closed 7 years ago.
I have a Logger class in my C++ application. This class has public methods like writeDebug(std::string & str) , can write to a debug output file and it works for me very good. The object is being created on application start by the first main class and there it is stored as a Logger * myLogger; object.
Since I have other classes as well, I would like to provide this logging functionality to those classes as well.
Currently I oberhead the myLogger pointer to toher classes in their contructor, and all the other classes store this very same Logger pointer when being created --> all other classes has this Logger * myLogger pointer stored:
Other_XY_Class::Other_XY_Class(Logger * logger, ...)
: localLoggerPtr{logger} { //.. }
==> localLoggerPtr (in class Other_XY_Class) == myLogger (in main application class)
I can imagine that there is a more convenient / elegant way to handle that ?
Since you only have one instance, why not use a Singleton for that?
Something along this lines:
class foo {
private:
void bar();
static foo Instance;
public:
static void Bar() { Instance.bar(); }
}
Related
This question already has answers here:
Unresolved external symbol on static class members
(6 answers)
Closed 7 years ago.
I'm currently designing some code on QT that is built across multiple source. I want to create an array in one source and be able to access it in another source.
Currently in my Header I have class
Array_Class : public QString
{
public:
static QString Data_Array [2];
};
I don't think I need a constructor as I'm going to "populate" the array before I read it.
currently in my source.cpp I have
Array_Class::Data_Array[0]= "foo";
Array_Class::Data_Array[1]= "bar";
however this gives me the error message undefined reference to "Array_Class::Data_Array". What am I missing? thanks
So far, you have only declared your array:
Array_Class : public QString
{
public:
static QString Data_Array [2]; // -> only a declaration!
};
In order to use it, you must now define it. To do this, you need to place somewhere in your .cpp:
QString Array_Class::Data_Array [2];
This question already has answers here:
Defining static members in C++
(6 answers)
Closed 7 years ago.
I need a class with static std::vector<int> simples (first N simple numbers). I created it in static method __init__, which is called before any instance of MyClass is created:
class MyClass
{
public:
MyClass()
{
/* I need to use MyClass::simples here */
printf("%d\n", (int)MyClass::simples.size());
/* But I get the error here :( */
}
static void __init__(int N)
{
simples.push_back(2);
/* ...
here I compute first N simple numbers and fill
MyClass::simples with them
*/
}
private:
static std::vector<int> simples;
};
int main()
{
MyClass::__init__(1000);
MyClass var;
return 0;
}
But when I tried to use this vector in construction, I get undefined reference to 'MyClass::simples' error. How to solve my problem?
When defining a static member in C++, you need to write it two times: first in class definition as you did:
static std::vector<int> simples;
And then outside (preferably in an external .cpp file):
std::vector<int> MyClass::simples;
If you know about C language, this can help you: static members in C++ are comparable from global variables in C: defined as a prototype in .h file included whenever you need it, and value initialized in one .c/.cpp file.
You have to define the static data member outside the class
std::vector<int> MyClass::simples;
Within the class definition it is only declared.
This question already has answers here:
Using derived methods that aren't in the base class
(2 answers)
Closed 8 years ago.
Say I have a class Person, and its subclass Boy. I want to include a method within Boy which Person does not have, and to be able to use through polymorphism in the following manner:
Boy john = Boy();
Person* personP = &john;
personP->boyFunction();
I've tried declaring the function in Person as virtual and =0 (in the header file). The problem is that I have multiple functions such as this one, and I don't want ALL subclasses to define ALL those functions.
How is this done neatly and safely, assuming I want to have multiple different subclasses of Person, each having a function exclusive to itself?
You have options. It depends on what exactly is the situation in which you want to call boyFunction(). If you know it has to be a Boy*, then you should require that you get a Boy*. Otherwise...
Most direct: the cast (though this is probably an indication of poor design), only call boyFunction() if applicable:
Boy* boy = dynamic_cast<Boy*>(personP);
if (boy) {
boy->boyFunction();
}
Less direct, more pollution:
class Person {
// ...
virtual void boyFunction() { } // probably not = 0;
}
class Boy : public Person {
// ...
void boyFunction() { /* do stuff */ }
};
personP->boyFunction();
Why do you want to call boyFunction()? Maybe it's part of some larger algorithm... so wrap what you want to do in a larger dynamic method:
personP->performSomeFunction();
Where maybe:
void Boy::performSomeFunction() {
a();
b();
boyFunction();
c();
}
but
void Doctor::performSomeFunction() {
doSurgery();
}
This question already has answers here:
Is there a way to instantiate objects from a string holding their class name?
(12 answers)
Closed 8 years ago.
I'm working on a game and am trying to implement a smart way to create npc-objects in C++ from parsing a text file.
Currently this is hard coded in a Factory-object. Like this:
IActor * ActorFactory::create(string actortype, Room * r, string name, int hp)
{
if(actortype == "Troll")
{
return new Troll(r, name, hp);
}
if (actortype == "Dragon")
{
return new Dragon(r, name, hp);
}
// ... and so on
throw "Can't recognize type '"+actortype+"'.";
}
This is in my opinion a very ugly way to do it. Since it (among other things) breaks the Open/Closed principle.
I am schooled in Java, and in Java I would do something like having each IActor report it's class name and class type to the ActorFactory in the beginning of program execution. The factory would then store the relation in a map and can then easily look up what string maps to which object and it can then easily instantiate it.
Edit: I would also like to have the ability to call the constructor with a variable number/type of arguments.
How would this be done in C++? Can it be done?
In C++, you would typically use the Abstract Factory design pattern.
The point is: "the decision about the type of actor to create should not be the responsibility of ActorFactory::create()." In your case, this method should not decide which class to instantiate based on a string but would rather rely on a type; this type is the actual factory class.
Each actor class has its own factory class: TrollFactory, DragonFactory, etc. deriving from a base class ActorFactory2 (trailing 2 because ActoryFactory is already taken);
Each specialized factory class implements a virtual create() method without parameter returning a pointer to a newly created actor class;
If you need parameters to construct an actor, pass them to the factory object before creating the actor: pass them in the ctor and store them as member variables; create() will retrieve them later upon creation of the actor;
This way, you can easily pass different arguments for different actors and your factory mechanism will be scalable (a step toward the Open/Closed principle);
Now, ActorFactory::create() accepts a pointer to an object deriving from ActorFactory2 and calls the ActorFactory2::create() method: it will create the requested actor with appropriate arguments without switch statement.
class ActorFactory2
{
string m_name; // Each IA actor has a name
int m_hp; // and some HP
public:
ActorFactory2( const string &p_name, int p_hp )
: m_name( p_name ), m_hp( p_hp ) {}
virtual IActor * create() const = 0;
};
class TrollFactory : public ActorFactory2
{
// No special argument needed for Troll
public:
TrollFactory( const string &p_name, int p_hp )
: ActorFactory2( p_name, p_hp ) {}
virtual IActor * create() const { return new Troll( m_name, m_hp ); }
};
class DragonFactory : public ActorFactory2
{
FlameType m_flame; // Need to indicate type of flame a dragon spits
public:
DragonFactory( const string &p_name, int p_hp, const FlameType &p_flame )
: ActorFactory2( p_name, p_hp )
, m_flame( p_flame ) {}
virtual IActor * create() const { return new Dragon( m_name, m_hp, m_flame ); }
};
IActor * ActorFactory::create( const ActorFactory2 *factory )
{
return factory->create();
}
int main( int, char ** )
{
ActorFactory af;
...
// Create a dragon with a factory class instead of a string
ActorFactory2 *dragonFactory = new DragonFactory( "Fred", 100, RedFlames );
IActor *actor = af.create( dragonFactory ); // Instead of af.create( "dragon", ... )
delete dragonFactory;
}
I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns
The specific term is: parameterized factory method and it is part of the factory method design pattern.
To use a generic factory, hold the classes in a map and access via a string. If your class names are usable, register the class to the factory with "typeid(MyClass).name() and return a copy of the class by providing a clone() member function.
However, for simple not to extensible factories, I use the approach from your question.
I can't answer your question about passing more variable parameters, but to deserialize, it is enough to pass the portion to the class and let it deserialize itself (as you already seem to do).
You could use a map to store function pointers that'd return Actor*, with that being a pointer to the object being created. so then the code would just be
std::map<std::string,IActor* (*) (Room*,std::string,int)> constructorMap
constructorMap["Troll"]=&TrollConstructor
//etc...
IACtor* ActorFactory::create(string actortype,Room* r,string name,int hp){
return (*constructorMap[actortype])(r,name,hp);
}
(please excuse any possible screw-ups I made with the function pointers, they are not my strong point)
I have a situation where I have an interface that defines how a certain class behaves in order to fill a certain role in my program, but at this point in time I'm not 100% sure how many classes I will write to fill that role. However, at the same time, I know that I want the user to be able to select, from a GUI combo/list box, which concrete class implementing the interface that they want to use to fill a certain role. I want the GUI to be able to enumerate all available classes, but I would prefer not to have to go back and change old code whenever I decide to implement a new class to fill that role (which may be months from now)
Some things I've considered:
using an enumeration
Pros:
I know how to do it
Cons
I will have to update update the enumeration when I add a new class
ugly to iterate through
using some kind of static list object in the interface, and adding a new element from within the definition file of the implementing class
Pros:
Wont have to change old code
Cons:
Not even sure if this is possible
Not sure what kind of information to store so that a factory method can choose the proper constructor ( maybe a map between a string and a function pointer that returns a pointer to an object of the interface )
I'm guessing this is a problem (or similar to a problem) that more experienced programmers have probably come across before (and often), and there is probably a common solution to this kind of problem, which is almost certainly better than anything I'm capable of coming up with. So, how do I do it?
(P.S. I searched, but all I found was this, and it's not the same: How do I enumerate all items that implement a generic interface?. It appears he already knows how to solve the problem I'm trying to figure out.)
Edit: I renamed the title to "How can I keep track of... " rather than just "How can I enumerate..." because the original question sounded like I was more interested in examining the runtime environment, where as what I'm really interested in is compile-time book-keeping.
Create a singleton where you can register your classes with a pointer to a creator function.
In the cpp files of the concrete classes you register each class.
Something like this:
class Interface;
typedef boost::function<Interface* ()> Creator;
class InterfaceRegistration
{
typedef map<string, Creator> CreatorMap;
public:
InterfaceRegistration& instance() {
static InterfaceRegistration interfaceRegistration;
return interfaceRegistration;
}
bool registerInterface( const string& name, Creator creator )
{
return (m_interfaces[name] = creator);
}
list<string> names() const
{
list<string> nameList;
transform(
m_interfaces.begin(), m_interfaces.end(),
back_inserter(nameList)
select1st<CreatorMap>::value_type>() );
}
Interface* create(cosnt string& name ) const
{
const CreatorMap::const_iterator it
= m_interfaces.find(name);
if( it!=m_interfaces.end() && (*it) )
{
return (*it)();
}
// throw exception ...
return 0;
}
private:
CreatorMap m_interfaces;
};
// in your concrete classes cpp files
namespace {
bool registerClassX = InterfaceRegistration::instance("ClassX", boost::lambda::new_ptr<ClassX>() );
}
ClassX::ClassX() : Interface()
{
//....
}
// in your concrete class Y cpp files
namespace {
bool registerClassY = InterfaceRegistration::instance("ClassY", boost::lambda::new_ptr<ClassY>() );
}
ClassY::ClassY() : Interface()
{
//....
}
I vaguely remember doing something similar to this many years ago. Your option (2) is pretty much what I did. In that case it was a std::map of std::string to std::typeinfo. In each, .cpp file I registered the class like this:
static dummy = registerClass (typeid (MyNewClass));
registerClass takes a type_info object and simply returns true. You have to initialize a variable to ensure that registerClass is called during startup time. Simply calling registerClass in the global namespace is an error. And making dummy static allow you to reuse the name across compilation units without a name collision.
I referred to this article to implement a self-registering class factory similar to the one described in TimW's answer, but it has the nice trick of using a templated factory proxy class to handle the object registration. Well worth a look :)
Self-Registering Objects in C++ -> http://www.ddj.com/184410633
Edit
Here's the test app I did (tidied up a little ;):
object_factory.h
#include <string>
#include <vector>
// Forward declare the base object class
class Object;
// Interface that the factory uses to communicate with the object proxies
class IObjectProxy {
public:
virtual Object* CreateObject() = 0;
virtual std::string GetObjectInfo() = 0;
};
// Object factory, retrieves object info from the global proxy objects
class ObjectFactory {
public:
static ObjectFactory& Instance() {
static ObjectFactory instance;
return instance;
}
// proxies add themselves to the factory here
void AddObject(IObjectProxy* object) {
objects_.push_back(object);
}
size_t NumberOfObjects() {
return objects_.size();
}
Object* CreateObject(size_t index) {
return objects_[index]->CreateObject();
}
std::string GetObjectInfo(size_t index) {
return objects_[index]->GetObjectInfo();
}
private:
std::vector<IObjectProxy*> objects_;
};
// This is the factory proxy template class
template<typename T>
class ObjectProxy : public IObjectProxy {
public:
ObjectProxy() {
ObjectFactory::Instance().AddObject(this);
}
Object* CreateObject() {
return new T;
}
virtual std::string GetObjectInfo() {
return T::TalkToMe();
};
};
objects.h
#include <iostream>
#include "object_factory.h"
// Base object class
class Object {
public:
virtual ~Object() {}
};
class ClassA : public Object {
public:
ClassA() { std::cout << "ClassA Constructor" << std::endl; }
~ClassA() { std::cout << "ClassA Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassA"; }
};
class ClassB : public Object {
public:
ClassB() { std::cout << "ClassB Constructor" << std::endl; }
~ClassB() { std::cout << "ClassB Destructor" << std::endl; }
static std::string TalkToMe() { return "This is ClassB"; }
};
objects.cpp
#include "objects.h"
// Objects get registered here
ObjectProxy<ClassA> gClassAProxy;
ObjectProxy<ClassB> gClassBProxy;
main.cpp
#include "objects.h"
int main (int argc, char * const argv[]) {
ObjectFactory& factory = ObjectFactory::Instance();
for (int i = 0; i < factory.NumberOfObjects(); ++i) {
std::cout << factory.GetObjectInfo(i) << std::endl;
Object* object = factory.CreateObject(i);
delete object;
}
return 0;
}
output:
This is ClassA
ClassA Constructor
ClassA Destructor
This is ClassB
ClassB Constructor
ClassB Destructor
If you're on Windows, and using C++/CLI, this becomes fairly easy. The .NET framework provides this capability via reflection, and it works very cleanly in managed code.
In native C++, this gets a little bit trickier, as there's no simple way to query the library or application for runtime information. There are many frameworks that provide this (just look for IoC, DI, or plugin frameworks), but the simplest means of doing it yourself is to have some form of configuration which a factory method can use to register themselves, and return an implementation of your specific base class. You'd just need to implement loading a DLL, and registering the factory method - once you have that, it's fairly easy.
Something you can consider is an object counter. This way you don't need to change every place you allocate but just implementation definition. It's an alternative to the factory solution. Consider pros/cons.
An elegant way to do that is to use the CRTP : Curiously recurring template pattern.
The main example is such a counter :)
This way you just have to add in your concrete class implementation :
class X; // your interface
class MyConcreteX : public counter<X>
{
// whatever
};
Of course, it is not applicable if you use external implementations you do not master.
EDIT:
To handle the exact problem you need to have a counter that count only the first instance.
my 2 cents
There is no way to query the subclasses of a class in (native) C++.
How do you create the instances? Consider using a Factory Method allowing you to iterate over all subclasses you are working with. When you create an instance like this, it won't be possible to forget adding a new subclass later.