I will describe the problem as simple as i can.
alright, here goes the problem;
Lets suppose we have a com component class with 3 of constructors where a constructor takes at least two of parameters. As we already know we instantiate the components via QueryInterface rather calling the classes' constructors therefore it seems it is not possible for a com client to set the constructor's parameters.
alright, here goes the question;
What is the best practical approach to allow a com client to instantiate a com component which requires at least two of parameters to be initialized?
Instead of directly returning object instances, your QueryInterface call can return factories. For example, instead of:
// implements IMyClass1 interface
return new MyClass1();
You would do:
// pointer to member that implements IMyClassFactory interface
return &m_myClassFactory;
// this could also be a static class instead of an object instance
The IMyClassFactory interface would have a create method that takes in the constructor arguments and returns the ultimate MyClass1 instance.
If its a pure COM component, the standard way of handling this is to implement Initialize(foo, bar) methods instead of separate constuctors and then call that immediately after COM instantiation. If the object has no sensible default state, then you can make it a member variable (pointer) in a COM object. From that COM object you will have your Initialize(foo, bar) functions. In each of these initialize function the correct version of your object will be instantiated. Every pass through function in your COM wrapper will need to check that your object is not NULL and return an appropriate HRESULT if it is.
One option would be to use a factory object; the creation functions would be all on the (stateless) factory object (on a different interface, of course), and pass back an initialized instance of the real object.
When I write COM servers, I don't usually allow my components to be instantiated by CoCreateInstance. Instead I export some bare functions (these can be described in IDL as well inside a module) from my DLL which accept the constructor parameters and return an interface pointer to the newly created object in an output parameter.
I like both Ates Goral's answer and Steve's and have upvoted both. Normally I would leave it at that, but I feel that this time I have to spell out my full take.
The "best", "right", "purest", "canonical" way to do this is undoubtely the factory pattern, as described by Ates. If you want to create a clean API, that's the road, hands down.
But... most of us are not busy creating public APIs for commercial products. For small internal projects with non-public APIs, I just want to get the job done. Having to implement an extra object just so I can expose a single factory method sounds rather overkill (particularly in C++). In most practical cases, I would just go for an Initialize(foo, bar) method as described by Steve. I would then make sure that every non-trivial method checks to see if the object has been initialized and returns a failure HRESULT if not.
Related
I found about four different ways to instantiate the object, but not sure if my understanding is clear.
NewObject<T>() function used when we want to make at the instance of UObject. For example, it can be any ActorComponents.
USomeComponent sc = NewObject<USomeComponent> (class);
ConstructObject<T>() one more way to init UObject...
CreateDefaultSubobject<T>() but using this one function we also can create an instance of any class inherited from UObject.
SpawnActor<T>() used for instantiating an object of AActor class.
So first question: What is the difference if we can use these functions for one purpose? How and when and why we need to use any of them?
To understand the difference between these functions, you need to remember that the object model
in Unreal Engine is based on object prototypes, very much like in JavaScript. Each UClass is associated
to a default instance of the associated UObject class, called the Class Default Object (CDO), which is
allocated first and then constructed, only once, via the class constructor when the engine is initialised.
The CDO acts as a template from which all other instances of the class are copied, and the constructor is
never called again.
This means class constructors cannot contain any runtime logic, and should only be used to
initialise the CDO and its properties. If the class contains any subobjects, like actor components,
these must do the same, so their own default objects must be constructed first. The actual instantiation of
the object must then be deferred, after the engine has initialised, so that every time a new instance of the class is
requested to be created by normal gameplay code, the parent object and all of its subobjects are instantiated from their respective defaults.
So, the multiple ways of creating objects are necessary to handle all the different
scenarios where an object may be created.
UObject::CreateDefaultSubobject is only callable in a class constructor, and takes care of creating an instance of the CDO
of the subobject's class, setting its outer class as the caller object,
among other things. The created object then becomes the default object for the property when its object class is instantiated.
NewObject<T> is the function normally used to instantiate objects after engine initialisation, during normal gameplay. It
provides several convenience overloads to handle most scenarios.
UWorld::SpawnActor<T> is a convenience method to spawn actors in a level with the specified location and rotation,
spawn collision settings, and checks to ensure it's a spawnable actor class, and is nothing more than a wrapper of
NewObject<AActor>.
ConstructObject has been removed in favour of NewObject.
I recommend checking the engine source code for more information, especially UObject/UObjectGlobal.cpp
and UObject/UObjectGlobal.h in the CoreUObject engine module. Internally, all these function ultimately call (as of 4.24)
StaticConstructObject_Internal, which handles the actual object creation.
I have a connection manager which currently has a static reference to a class which is kept inside the connection manager in the private section of the class. A pointer to this class is passed to all connections and they can use it for utility purposes.
Now this class pointer is not immediately useful to the childs, but it is useful for the childs own children, so all that happens is that it's passed along.
Now I'm wondering that since there is only ever 1 instance of this utility class should I bother with all this passing around of the pointer, or would it be better to make the class a singleton and each class that requires it can simply use a static getInstance() method instead. This would mean that classes that don't care about it don't need to know about it.
There are lots of types of connections (30+) and none of them care about the utility class.
However, they will use classes (at the moment, just 2) that do care about the utility class.
I'm not sure if every type of connection should burden itself with something it doesn't care about, just for the sake of a couple of classes that it (may) use.
Singletons and static fields are generally considered evil. Why is it static anyway? It could happen so one day you'll need each connection manager to have its own reference.
The best idea I can think of is to make the reference non-static first. Then, forget about using the singletons. From this point you should start to think how to implement this in the most elegant way.
I don't know the nature of your class, but it sounds reasonable to me that each connection should have a reference (or a pointer) to the connection manager that manages it. Just in case.
Then, the connection manager should probably provide a getter for anyone who wants to access that utility class. Connections themselves should pass along either the reference to the connection manager or to the utility class depending on what makes more sense.
It also makes sense to pass the reference to the connection manager to the constructor of the common ancestor of the connections, if there is one (which it should be). This way, you no longer have 30+ classes that refer to something they don't really need, but just one abstract class that they are based upon.
And if you really want to do something singleton-like, then it's better to have a kind of static method with a parameter that returns the reference, as opposed to just a static method:
static UtilityClass *getInstance(int id);
// not static UtilityClass *getInstance();
Even if you don't use the id parameter right now, it may get very useful later, when you need multiple instances. You could have some sort of table or hash map that maps the id to the instance. You can even add a method that creates or replaces the instance for a specific id, which could be very useful for unit testing. Note that this approach still has at least the following disadvantages of the singleton pattern:
It is prone to various threading problems.
It still hides dependencies of your classes: that is, you can't say what a class uses just by looking at its API.
It is hard to give more advices without looking at the code.
If I understand you correctly, at the top layer there is a Connection Manager. It contains a static class which is useful later on.
The next layer down are many instances of a class which exists to service each of the connections managed by the aforementioned manager.
Each one of those may in turn use some instances of utility classes which would like access to information from the Connection Manager (in this case you've wrapped it up as the static object).
The question is how best should the 3rd layer down should gain access to the Connection Manager's contained information.
I'll call them: Manager (contains 'static class') -> Connection -> Utility
My suggestion would be to have the Connections take references to the Manager which owns them. They can't or shouldn't exist without it and they are managed by it. They in turn need to construct objects that need a specific bit of information from the Connection Manager (the static class contained within).
So when the Connection's construct the Utility classes, the Utility classes will require only the bit of information they need to operate (in this case a reference parameter for a class which happens to be static inside the Manager). They should take this by reference also. The Connection has the Manager class reference and is able to provide the constructor for the Utility the bit of information it needs to operate.
The reason I am suggesting this approach is:
Connections/Utility classes don't care whether the manager is a singleton (opens possibilities later if you need multiple managers)
Utility doesnt care whether static class is static. They only need a reference to a specific class they need.
Manager decides how it or its contained data needs to be allocated.
Lastly:
The only class which has reason to know about the other two main classes is the Connections class. It seems reasonable it might know which manager is managing it (and therefore some interface information). It also knows what the Utility classes it will require and what they will need in terms of construction params and other interface requirements.
To set this up there may be some funkiness with includes and classes may have to expose interfaces to each other but thats just standard fare anyway.
My 2c.
Singleton vs. Static
A good example of singleton usage: you wish only one instance to be running for a class, for example a texture manager, shader manager, connection pool manager etc. (see the pattern emerging:)
As an example lets take a connection pool manager: we want to create a single pool of connections that are managed and re-used by any other object that requires a connection in our code, so we make a ConnectionPoolManager singleton class, with say, 32 connections. This now allows every object requiring a connection to use a method, for example getFreeConnection, from the ConnectionPoolManager singleton, to retrieve a valid connection which can then be used as needed. This allows the ConnectionPoolManager to be the only part of the code anywhere that has anything to do with starting stopping and otherwise managing connections for your code.
Both singletons and static class can be implemented in such a way that they are thread-safe, however singletons have the advantage as they can implement interface (common), derive from other classes (less common), and a singleton can be passed around in exactly the same way as any other object (well a reference to it at least), where a static class can only implement static methods.
In regards of your specific case, you indicate that from 30+ classes only a couple require the utility class: the dependence on a singleton or static class is entirely up to your design and style. Should you wish a versatile way of doing it, with potential for change later, I would utilise a singleton. If you know that the static class will suffice and will not necessitate a redesign later, then go with that, or, if you have a particular liking for one or the other, use that one. There may also be hardware/software limitations and particulars which recommend one over the other, however that does not sound to be the case at the moment.
Let me know if you need more information, or if there are any particulars which you think may sway your choice one way or the other and I can provide information about pros and cons for each approach to suit your needs:)
/**
* A JavaScript value representing a signed integer.
*/
class V8_EXPORT Integer : public Number {
public:
static Local<Integer> New(Isolate* isolate, int32_t value);
static Local<Integer> NewFromUnsigned(Isolate* isolate, uint32_t value);
int64_t Value() const;
V8_INLINE static Integer* Cast(v8::Value* obj);
private:
Integer();
static void CheckCast(v8::Value* obj);
};
The above code is from Google's V8 engine. Example initialization of this is:
Handle<Value> x = Integer::New(42);
From what I can see in the source code, they marked the constructor as private and want you to use the New function to create instances of this class. Isn't this against the standard C++ design patterns? Why didn't they just overload the constructor instead of making static functions for creation? This usually the kind of thing you see when people try to port a library from one language to another (the only one I can think of off the top of my head right now is Xamarin's iOS kit).
I've tried to Google around for a name for this type of convention but was unable to find anything on it really.
This is a pattern called "Static Factory Method", which is recommended by Joshua Bloch as Item 1 in "Effective Java". (I am almost sure that Scott Myers has an equivalent Item in "Effective C++", but right now I do not have a copy of the book to check.)
The advantages of creating objects through such a method, instead of the normal constructor, are described by Bloch as:
such methods may have a descriptive name
unlike constructors, such methods are not required to create an entirely new object, i.e. they can return a previously cached copy of
the object.
unlike constructors, such methods may also return an object of any subtype of their return type
such methods reduce verbosity of parameterized object construction
There are also downsides to this design pattern, it is only a recommendation in certain situations.
Probably, in the case of V8, the second point in the list is most important, in order to speed up construction. I am no V8 expert, but it seems that "event-driven, single-threaded" is its philosophy. When many "event callbacks" want to have one and the same number, all of them get a copy of the same instance of that number.
There are two types of handles. One of them is a "Local" handle. As shown in the code, local handles have the class Handle<SomeType>.
https://developers.google.com/v8/embed
Note: The handle stack is not part of the C++ call stack, but the
handle scopes are embedded in the C++ stack. Handle scopes can only be
stack-allocated, not allocated with new.
https://developers.google.com/v8/get_started
A handle is a pointer to an object. All V8 objects are accessed using handles, they are necessary because of the way the V8 garbage
collector works.
The most important reason to abstract away from low-level C++ constructors with factory methods is that allocation and construction need to be combined in this API. Most factory methods perform allocation. However, this allocation has to happen on the (garbage-colected) JavaScript heap, not the C++ heap. This has several consequences:
We cannot allow to construct raw objects without allocation, e.g. on the stack.
We cannot allow to use C++-side new.
We cannot allow to use raw pointers by default, because that would break garbage collection (handles are an indirection the GC is aware of and can update for relocation).
Factory methods help to enforce these restrictions.
Look's like they are using a static factory method. This can make sense when you want to centralize creation of objects because it must be done in a special way. I could imagine that the constructor provides a plain valid integer object and that the factory method than call additional methods to bring the object into a special initial state.
It is also a good idea to limit constructors to be as minimal as possible. Constructors should establish the invariant of the class. Additional settings can then be done by special methods, and creation of specifically initialized objects can be encapsulated in factories.
this is probably a noob COM question, but googling this raises more questions than providing answers:
Is it safe to use "operator new" instead of CoCreateInstance for a local COM instance?
What I've done:
I implemented the IOperationsProgressDialog interface
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775368(v=vs.85).aspx
by using public inheritence and thereby also implemented the IUnknown interface.
I created an instance via "new RecyclerProgressCallback" and put it into a COM-Ptr for life-time management. "RecyclerProgressCallback" is the name of my derived class.
I'm using this instance in IFileOperation::SetProgressDialog
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775803(v=vs.85).aspx
Summary: My approach "seems" to work, but I don't trust it, there's just too much disconcerting information around COM object creation to rely on the observable behavior only.
Are there any subtle risks, fallacies or other problems? Thanks!
I've even put them on the stack. Andrey's answer (now deleted) incorrectly suggested that it is unsafe, because you bypass COM reference counting. This is faulty reasoning. COM doesn't count references; it delegates the responsibility to you. You have to call delete, or free(), or whatever your language uses, after COM calls your Release method on its last interface. The important word is after. Not when, because you're not obliged to do so immediately.
Similarly, CoCreateInstance is a long detour because COM is language-neutral and doesn't know whether an object must be created with malloc or new. You do, so just bypass the whole COM logic.
It depends what exactly you are instantiating. When you are supposed to provide a COM pointer noone asks you whether it is instantiated with COM API, or new, or it can sometimes be even object on stack (provided that you manage to ensure it is not destroyed on stack before all references are released).
So the answer is yes, you can use new and it would be fine. However, it should be a valid COM interface anyway, it should implement reference counting and QueryInterface the way COM objects do.
CoCreateInstance API will look at the registry find the module that match specified CLSID, load it and the through a mechanism(it depend whether your code is DLL or EXE) it will call some functions to create your object. So for your code in order to make CoCreateInstance to work, you should write a class that implement IClassFactory interface of COM and register it in the registry and then call CoCreateInstance that do a couple of extra work with your code to at least do your lovely operator new, then yes of course it is safe. In general it is always safe to call operator new of implementation of source interfaces(interfaces that only declared for callback) in your code and this is also the preferred way.
This will work fine. This is how a COM server would typically create its objects internally (at least one written in C++). From your point of view, the RecyclerProgressCallback class is just some C++ code. You can treat it as any other class in your program.
That being said, COM is a minefield of subtle gotchas. I can't promise that you won't encounter problems with your class, but I can assure you that those problems will be unrelated to your use of operator new.
It's generally not safe, not just because of reference counting but also because of marshalling: the class may have a threading model that requires marshalling. CoCreateInstance will create a proxy and stub if that's the case, whereas new will not.
I have the following problem.
I got a class PluginLoader which oversees loading of plugins. It divides sub-stages of work to other classes like Plugin. Plugin calls functions of PluginLoader in its processing. Let's call that function AddData. Here, PluginLoader has to check if the data it receives is duplicate. For that, it uses a ConflictResolver class. Now, my problem is how to make an object of ConflictResolver available to PluginLoader. There are 3 ways I see out of this.
Use a ConflictResolverFactory class and create an object of ConflictResolver for PluginLoader.
Pass a constructed ConflictResolver* to the PluginLoader via its constructor or a member function SetConflictResolver and store it in a member variable and use it later. Both ways have drawbacks. If I pass it in the constructor, I will have to throw if the pointer is NULL. And I can't use exceptions as it is the custom here. If I pass it via SetConflictResolver, there is no way that I can guarantee that that function will be actually called by the user. Or I will have to check whether the member ConflictResolver* is NULL everywhere I use it.
Pass a ConflictResolver & to PluginLoaders Load method where all the work will be done. In turn, Plugins Load method has to accept a ConflictResolver & as well (though it has no use for it) and pass that back to AddData where PluginLoader will be able to use it.
Third method is safer compared to second. However, I have to pass around a reference even when it is not used.
If the first method cannot be used, what is the best way to do this?
Apologies for the wall :wq!
You could pass a ConflictResolver& to the PluginLoader constructor. You can now guarantee that the object is not null.