I am writing a distributed programming framework and I have reached a wall on what it comes to templated object declaration and creation on client side. The problem is that I have a object that I need to create in the client side of the network. Somewhere in the client I have:
At Server Side:
template <typename T>
class myRemoteObject{
myRemoteObject<T>(){
// tells client to create an object of type T
sendCreateObject( encodeType(T) ); // This is working
}
};
int main(){
...
myRemoteObject obj;
...
}
At the client side:
case (message.type){
OBJ_TYPE_INT:
objPtr = new myObject<int>();
break;
OBJ_TYPE_FLOAT:
objPtr = new myObject<float>();
break;
}
That brings me lots of problems. First, it is not flexible because I have to explicitly declare every type I use inside my framework statically, if I want to also use containers (vector etc) I also would have to explicetly instantiate them.
Second, it is very slow to compile. myObject has a lot of templated functions and compiling just 4 of those instantiations would occupy 1.5G of ram and would take a while too. I got to the point that it would occupy 6GB of RAM and take more than 1h (never finished).
So, I opted for explicit instantiation. I created several .cpp files (12) that explicetly instantiated myObject with different types, declared myObject templates in a separate file and included just the .h containig template signatures in the code cited before. Although, that sill limits the frameworks capabilities and
Anybody knows a way to do that purely as a template? So I need to instantiate only the types being used by the main program? I tried to put the instantiation of myObject inside myRemoteObject, but it didn't work...
ps.: I am using C++2011
The problem is that you are trying to instantiate templates, which are solved at compilation time, with a data type of a message that is solved in run time, too late. My only suggestion is that you use an Abstract Factory design pattern http://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm , https://en.wikipedia.org/wiki/Abstract_factory_pattern with a getObject method. In the ConcreteFactory, in the implementation of getObject() or createObject(), you instantiate the corresponding object and return it.
Each ConcreteFactory creates an object of certain type (int, float, etc.) and returns it.
For any new type you could create a new plugin with the corresponding ConcreteFactory.
This can help you solve part of the problem.
Related
I've gotten into a bit of a design block in a C++ program of mine as two different header files are required to reference each other. Typically a forward declaration would be used here, but since both classes use template functions/constructors a forward declaration cannot be used as methods/variables from both classes need to be used.
For example consider the following scenario (this is pseudo code as an example, it may/may not compile. The objects are representative of my actual application so if a redesign is necessary then I'd love to understand the design philosophies of what I did wrong)
// Application.hpp
#include <Assets.hpp>
#include <Logger.hpp>
class Application {
public:
// Some brilliant code here ...
Logger myLogger;
template <int someArrayLen> Application(std::array<int, someArrayLen> myArr, SomeOtherTypes someOtherStuff) : myLogger(stuffHere) {
mainAssets = new Assets(myArr);
}
~Application(); // Assume this is implemented in Application.cpp and has delete mainAssets;
};
extern Application* mainApp; // Assume Application* mainApp = nullptr; in Application.cpp
// Assets.hpp
// #include <Application.hpp> ???? The issue lies here
class Assets {
private:
// Random data structures/stuff for holding shaders/textures/etc
protected:
template <int someArrayLen> Assets(std::array<int, someArrayLen> myArr) {
if (!shadersSupported()) {
// Main app is an unknown symbol
mainApp->myLogger->error("Your GPU is too old/whatever!");
}
// Random code for loading assets based on my template stuff
}
friend class Application;
public:
// Get assets/whatever here
};
extern Assets* mainAssets; // Assume Assets* mainAssets = nullptr; in Assets.cpp
How can I fix the compile error regarding mainApp being an unknown symbol? Any feedback/help is appreciated, thanks!
I've already looked through all the following questions but none address this unique scenario:
two classes referencing each other
This question had no use of templates so forward declarations could be used as the method bodies weren't defined in the headers
Two classes referencing each other with hash template specialization
The solution from this question cannot be used as here the compiler was unable to figure out how much memory to allocate, whereas in my question the issue isn't regarding the compiler being confused with how much to allocate but rather what to reference
Two template classes being composed of a member of each other
This question addressed a design flaw of circular dependencies which my application does not have, both classes are stored globally, they are just instantiated in separate constructors which reference each other.
Two classes that refer to each other
This question provides forward declarations as a solution which cannot be used here due to the requirement for using the class methods/constructors in template function definitions.
I've also already considered the following:
Trying to change from std::array to pointers, this wouldn't work as my Assets constructor does rely on the lengths of the array.
Trying to change from std::array to std::vector, I want to stick to aggregate initialization so it can be done at compile time, I believe vectors/lists would be too heavy for this.
Forward declarations will indeed work for your problem. The key is that function templates can be defined out of line (i.e., not in your class ... { }; declaration) legally. The same can be achieved for arbitrary functions using the inline keyword.
To now solve your specific problem, just split Application.hpp into Applicaton_fwd.hpp and Application.hpp - similar to iosfwd. Application_fwd.hpp contains almost all the code and Application.hpp includes Application_fwd.hpp and Assets.hpp before defining the Application::Application function template (just like you would define a function in a *.cpp file).
In Assets.hpp, you can simply use Application_fwd.hpp as long as you do not use the constructor. If you also use the Application constructor in Assets.hpp, things become a bit more complicated in that you need to very carefully consider all possible inclusion scenarios (i.e., what happens exactly every time one of your headers is included by themselves or a user) to make sure that it resolves in the order that you need it to without the guards causing trouble.
You can see it in action here
This is for a "game engine" as a bit of programming practice. All of my GameObjects are component based, where each component adds a functionality to its parent GameObject and all of these components descend from a base Component class which has virtual methods making it polymorphic.
When I read in these gameobject definitions from an XML file some components need to know about others for example a physics component needs to be aware of the transform component for the physics calculations. However if these components aren't present in the XML file then occasionally it throws up nasty null-pointers and endless rabbit hole call stack chasing to find the XML typo I fudged while half asleep.
My solution was to have a node in the XML file as an assertion that a component of this type should exist and possibly throw an exception or another appropriate action if it doesnt.
Eg.
<ComponentRequirement type="ComponentTransform">myTransformComponent</ComponentRequirement>
So I need a way of representing this in C++. The first idea, template classes to change according to what type of component it's the proxy of since this class needs to act like their unproxied component. I've solved that with some operator overloading so long as the class is a template class.
template <class T>
class ComponentRequirement {
public:
T* operator->() { (I chose the arrow operator because the CompReq class will never be referenced as a pointer)
return this->component;
}
//Other unrelated functions . . .
private:
T* component;
};
And this is all fine and dandy at compile time because I can just say
ComponentRequirement<ComponentTransform> req = ComponentRequirement("myComponentTransform");
But I need to be able to specify what that template type in place of the will be from a string when I read the XML in. I thought a hashmap could do it but I dont think the type name even "is" anything other than a human readable compiler hint so I couldn't use it as a hashmap value.
Can this be done and how could I go about implementing it? Inserting some string literal into a "black-box of magic" and get something that can be used as a template argument. And if it helps, everything that will be the value of "T" is polymorphic.
Or is there a better solution to my problem. It needs to be able to act as any Component I put into it and it needs to be discernable at runtime.
EDIT 1:
In my components I have a read and write function. If I read the component requirement in there I can make sure the template has the right value because each component is seperate.
I can then evaluate the requirements with a virtual function and a few functions in the gameobject class to check it's a valid configuration. This could solve the problem.
At a first glance I would use the factory pattern for your problem. That way you can create classes to create your objects given a different string without specifying the exact class you need at compile time unlike with normal typed constructors. The analogy I see people use are Virtual Constructors.
http://www.oodesign.com/factory-pattern.html
In essence you would have a map of factories (creator objects).
Define some top level interface for your components, such as IComponent.
Define a factory class for every component you want to generate that has a Create Instance method. I recommend the Create Instance method should be part of an interface like IFactory.
During setup of your program create your map and assign factories to particular keys. ActorCreator["MyComponent"] = new MyComponentFactory();
When you want to create an object read from an XML node you can just call the create instance method on the returned factory for the key. auto myComponent = ActorCreator[readXML]->CreateInstance();
You now have an actor/components whose concrete type has been decided at runtime instead of compile time.
I've had this problem tickling me for the past weeks; my current implementation works, but I'm curious to know if there is a "good way" to do this. I'm new to design patterns, so this might be a stupid question.
Put simply, you have:
An object prototype providing an interface (let's call it abstract kernel);
Specific kernels implementing the above interface in various ways;
A concrete kernel Factory;
Another object Foo, which stores a pointer to an abstract kernel, as is returned by the Factory.
My problem is this; specific kernels implementations may define their own set of parameters, which differ from one kernel to another.
Foo uses kernels to do some processing, but this processing ultimately depends on these parameters, and I don't know how to configure those in a nice way.
I don't want to go for an abstract factory, and configure the concrete factory before building, because this seems wrong to me; it's not the factory that has parameters, it's the kernel.
But on the other hand, even if I set the kernel pointer in Foo as public, I can't access the parameters of the underlying kernel since they're not part of the prototype's interface... I'm sure other people had this problem before, maybe there's a simple solution I don't see. :S
Thanks in advance!
NOTE: In my current implementation, there is no kernel Factory. I put the kernel concrete type as a template of Foo, and set the kernel as a public member, which allows me to configure the kernel after the declaration, and before to start the processing.
If a piece of code knows what concrete kind of kernel it works with, it should have a pointer to that specific concrete kernel type. If it doesn't, it cannot access its specific parameters (but can possibly access all parameters in a generic way as suggested by #Jaywalker).
Your current implementation seems to go the first route, which is perfectly OK.
I have very limited info about your design, but it looks like you have several concrete kernel types, a separate builder for each type, and a separate configurator for each type. Packing all the builders into a Factory is problematic, as there's no clean and elegant way to forward concrete kernel types to their respective configurators (without things like *_cast<> or double dispatch). There are at least two ways to solve this and still have a Factory:
Bundle each builder with its respective configurator, and pack all the bundles into a Factory that churns out configured kernels.
Bundle each kernel with its configurator and make a Factory producing these bundles (this way a kernel may be configured any number of times during its life cycle).
Anything which is not part of the prototype interface will not be available in Foo, as you have said. It simply doesn't make sense to use the factory pattern if Foo knows the specifics of each kernel implementation.
In some limited circumstances, adding something like following getters and setters in the prototype interface could get your work done:
virtual bool setParameter (const string &key, const string &value) = 0;
virtual string getParameter (const string &key) = 0;
I'm working on a sound library (with OpenAL), and taking inspiration from the interface provided by FMOD, you can see the interface at this link.
I've provided some concepts like: Sound, Channel and ChannelGroup, as you can see through FMOD interface, all of those classes have a private constructor and, for example, if you would create a Sound you mast use the function createSound() provided by the System class (the same if you would create a Channel or a ChannelGroup).
I'd like to provide a similar mechanism, but I don't understand how it work behind. For example, how can the function createSound() create a new istance of a Sound? The constructor is private and from the Sound interface there aren't any static methods or friendship. Are used some patterns?
EDIT: Just to make OP's question clear, s/he is not asking how to create a instance of class with private constructor, The question is in the link posted, how is instance of classes created which have private constructor and NO static methods or friend functions.
Thanks.
Hard to say without seeing the source code. Seems however that FMOD is 100% C with global variables and with a bad "OOP" C++ wrapper around it.
Given the absence of source code and a few of the bad tricks that are played in the .h files may be the code is compiled using a different header file and then just happens to work (even if it's clearly non-standard) with the compilers they are using.
My guess is that the real (unpublished) source code for the C++ wrapper is defining a static method or alternatively if everything is indeed just global then the object is not really even created and tricks are being played to fool C++ object system to think there is indeed an object. Apparently all dispatching is static so this (while not formally legal) can happen to work anyway with C++ implementations I know.
Whatever they did it's quite ugly and non-conforming from a C++ point of view.
They never create any instances! The factory function is right there in the header
/*
FMOD System factory functions.
*/
inline FMOD_RESULT System_Create(System **system)
{ return FMOD_System_Create((FMOD_SYSTEM **)system); }
The pointer you pass in to get a System object is immediately cast to a pointer to a C struct declared in the fmod.h header.
As it is a class without any data members who can tell the difference?
struct Foo {
enum Type {
ALPHA,
BETA_X,
BETA_Y
};
Type type () const;
static Foo alpha (int i) {return Foo (ALPHA, i);}
static Foo beta (int i) {return Foo (i<0 ? BETA_X : BETA_Y, i);}
private:
Foo (Type, int);
};
create_alpha could have been a free function declared friend but that's just polluting the namespace.
I'm afraid I can't access that link but another way could be a factory pattern. I'm guessing a bit, now.
It is the factory pattern - as their comment says.
/*
FMOD System factory functions.
*/
inline FMOD_RESULT System_Create(System **system) { return FMOD_System_Create((FMOD_SYSTEM **)system); }
It's difficult to say exactly what is happening as they don't publish the source for the FMOD_System_Create method.
The factory pattern is a mechanism for creating an object but the (sub)class produced depends on the parameters of the factory call. http://en.wikipedia.org/wiki/Factory_method_pattern
I am writing a library of utility classes, many of which are singletons. I have implemented them as such using inheritance:
template <class T>
class Singleton {
public:
T& getInstance() {
if(m_instance == 0) {
m_instance = new T;
}
return m_instance;
}
private:
static T* m_instance;
};
class SomeClass : public Singleton<SomeClass> {
public:
SomeClass() {}
virtual ~SomeClass() {}
void doSomething() {;}
};
Obviously this is a simple example, not an actual class. Anyways, I am finding that using code such as:
SomeClass::getInstance().doSomething();
Will create more than one instance of SomeClass. I am thinking this may be due to the fact that it is being used outside my library (.a) file as well as internally. For example, I am using a UI library not written by myself which is separately compiled and to which I am making additions. Some of these additions utilize singletons which are also being used in my .a library.
Is the separate compilation causing this? Something else?
The only way I have managed to get around the issue is to create a global object in my main.cpp file which I initialize with any singletons I will need. Then all code accesses this common global object with calls such as:
GlobalObject::getSomeClass().doSomething()
I hate having to add an additional method to this object every time I create another singleton. Plus the syntax seems clearer and more familiar using the first access method:
SomeClass::getInstance().doSomething();
Please let me know if you have any thoughts, opinions, etc.
Thanks.
Your problem is that your template is going to be instantiated in more than one compilation unit as it is completely inline. Therefore in every compilation unit that uses the template you will end up creating one singleton (per compilation unit). What you would need is to force global linkage, so that all compilation units reference the same template instantiation. The upcoming C++ standard will support this via extern template. What you can do now is to disable automatic instantiation in your project and manually instantiate the templates that you use explicitly. This way when you use the template in any compilation unit you will generate an unknown reference to the implementation which can then be satisfied by the linker from the (one) compilation unit where you do the explicit instantiation.
Are multiple threads accessing getInstance at the same time? That could cause multiple instances to be created. Consider:
Thread 1 executes the "if (m_instance==0)" and finds it true
Thread 2 executes the "if (m_instance==0)" and finds it true
Thread 1 allocates a new T
Thread 2 allocates a new T
Then one of them overwrites the other, and returns either one of the instances or the other (depending on compiler optimizations, etc.)
Every template class you create from Singleton is going to have it's own static m_instance member... those are not shared across the different classes because when the templates are instantiated, it actually generates different classes for each set of template parameters. Judging by the way you're doing your inheritance, this probably means that you'll end up with an instance of Singleton for every one of the classes that derive from it. Perhaps this is the cause of your issue?