DECLARE_DYNCREATE provides exactly the same feature of DECLARE_DYNAMIC along with its dynamic object creation ability. Then why should anyone use DECLARE_DYNAMIC instead of DECLARE_DYNCREATE?
The macros are documented to provide different functionality.
DECLARE_DYNAMIC:
Adds the ability to access run-time information about an object's class when deriving a class from CObject.
This provides the functionality for introspection, similar to RTTI (Run-Time Type Information) provided by C++. An application can query a CObject-derived class instance for its run-time type through the associated CRuntimeClass Structure. It is useful in situations where you need to check that an object is of a particular type, or has a specific base class type. The examples at CObject::IsKindOf should give you a good idea.
DECLARE_DYNCREATE:
Enables objects of CObject-derived classes to be created dynamically at run time.
This macro enables dynamic creation of class instances at run-time. The functionality is provided through the class factory method CRuntimeClass::CreateObject. It can be used when you need to create class instances at run-time based on the class type's string representation. An example would be a customizable GUI, that is built from an initialization file.
Both features are implemented through the same CRuntimeClass Structure, which may lead to the conclusion that they can be used interchangeably. In fact, code that uses an inappropriate macro will compile just fine, and expose the desired run-time behavior. The difference is purely semantic: The macros convey different intentions, and should be used according to the desired features, to communicate developer intent.
There's also a third related macro, DECLARE_SERIAL:
Generates the C++ header code necessary for a CObject-derived class that can be serialized.
It enables serialization of respective CObject-derived class instances, for example to a file, memory stream, or network socket. Since the deserialization process requires dynamic creation of objects from the serialized stream, it includes the functionality of DECLARE_DYNCREATE.
Put together, the following list should help you pick the right macro for your specific scenarios:
Use DECLARE_DYNAMIC if your code needs to retrieve an object's run-time type.
Use DECLARE_DYNCREATE if, in addition, you need to dynamically create class instances based on the type's string representation.
Use DECLARE_SERIAL if, in addition, you need to provide serialization support.
You're asking "why buy a Phillips screwdriver when I own a flathead?" The answer is that you should use the tool that suits your needs: if you need to drive only flathead screws, don't buy a Phillips driver. Otherwise, buy one.
If you need the features provided by DECLARE_DYNCREATE (e.g. because you're creating a view that's auto-created by the framework when a document is opened) then you should use DECLARE_DYNCREATE and if you don't and DECLARE_DYNAMIC works, you should use it.
Related
Following my reading of the article Programmers Are People Too by Ken Arnold, I have been trying to implement the idea of progressive disclosure in a minimal C++ API, to understand how it could be done at a larger scale.
Progressive disclosure refers to the idea of "splitting" an API into categories that will be disclosed to the user of an API only upon request. For example, an API can be split into two categories: a base category what is (accessible to the user by default) for methods which are often needed and easy to use and a extended category for expert level services.
I have found only one example on the web of such an implementation: the db4o library (in Java), but I do not really understand their strategy. For example, if we take a look at ObjectServer, it is declared as an interface, just like its extended class ExtObjectServer. Then an implementing ObjectServerImpl class, inheriting from both these interfaces is defined and all methods from both interfaces are implemented there.
This supposedly allows code such as:
public void test() throws IOException {
final String user = "hohohi";
final String password = "hohoho";
ObjectServer server = clientServerFixture().server();
server.grantAccess(user, password);
ObjectContainer con = openClient(user, password);
Assert.isNotNull(con);
con.close();
server.ext().revokeAccess(user); // How does this limit the scope to
// expert level methods only since it
// inherits from ObjectServer?
// ...
});
My knowledge of Java is not that good, but it seems my misunderstanding of how this work is at an higher level.
Thanks for your help!
Java and C++ are both statically typed, so what you can do with an object depends not so much on its actual dynamic type, but on the type through which you're accessing it.
In the example you've shown, you'll notice that the variable server is of type ObjectServer. This means that when going through server, you can only access ObjectServer methods. Even if the object happens to be of a type which has other methods (which is the case in your case and its ObjectServerImpl type), you have no way of directly accessing methods other than ObjectServer ones.
To access other methods, you need to get hold of the object through different type. This could be done with a cast, or with an explicit accessor such as your ext(). a.ext() returns a, but as a different type (ExtObjectServer), giving you access to different methods of a.
Your question also asks how is server.ext() limited to expert methods when ExtObjectServer extends ObjectServer. The answer is: it is not, but that is correct. It should not be limited like this. The goal is not to provide only the expert functions. If that was the case, then client code which needs to use both normal and expert functions would need to take two references to the object, just differently typed. There's no advantage to be gained from this.
The goal of progressive disclosure is to hide the expert stuff until it's explicitly requested. Once you ask for it, you've already seen the basic stuff, so why hide it from you?
I want to use derived attributes and references in an ecore model, but so far I have not found any documentation on how to set the code for the methods which compute the values of derived attributes/references.
As far as I understand it, the basic workflow is to mark an attribute/reference as derived, generate model code, and then manually add the implementation. However, I work with models dynamically generated through the Ecore API. Is there a way to take a String and specify this String as the implementation for the computation of the derived feature, without manually editing generated files?
EDIT>
To clarify: I'm looking for a way to directly change the generated Java files, by specifying method bodys (as strings) for the getters of derived EStructuralFeatures.
EMF provides a way of dealing with dedicated implementation for EOperation and derived EAttribute using "invocation delegate". This functionality allows you to put some implementation directly in your ecore metamodel in a string format (as soon as the used language can be "handled" by EMF, i.e, an invocation delegate exists).
As far as I know, OCL is well supported: https://wiki.eclipse.org/OCL/OCLinEcore#Invocation_Delegate
The registration of the invocation delegate is performed either by plugin registration or by hand (for standalone usage), and the mechanism works with the EMF reflection layer (dynamic EMF): https://wiki.eclipse.org/EMF/New_and_Noteworthy/Helios#Registering_an_Invocation_Delegate
(Please note that I never experienced this mechanism. I know it exists, but I never played with it.)
EDIT>
It seems that the question was not related to dynamic code execution for derived attribute, but to code injection (I misunderstood the "Is there a way to take a String and specify this String as the implementation for the computation of the derived feature?").
EMF provides a way of injecting code placed on the ecore metamodel directly into the generated code.
Here is the way for EAttribute with derived property. The EAttribute should have the following properties set to true: {derived volatile} (you can also add transient). If you only want a getter and no setter for your EAttribute, you can also set the property changeable to false.
Once your EAttribute is well "configured", you have to add a new EAnnotation with the source set to http://www.eclipse.org/emf/2002/GenModel and an entry with the key set to get and value set to your code that will be injected (see image below).
And voilĂ , your code will be generated with the value value injected in your getter.
You can add the same process for EOperation using body instead of get.
I'm writing a program that requires the user to be very flexible in manipulating data on a given object. I figured I would use a property browser of some kind; Qtilities' ObjectDynamicPropertyBrowser caught my eye.
However, I need to be able to add my own data types. The documentation is not clear on how to do so.
How can I allow my own data types to be represented in Qtilities' property browser widgets?
Also, more about my needs:
The data types are not part of Qt, nor are they even Q_OBJECTs.
Qt-specific modifications to the relevant classes are not an option.
Declaring the relevant classes via Q_DECLARE_METATYPE is okay.
In particular, I need to represent vector and matrix types (and possibly more later).
The browser you refer to depends on the QObject property system. So, unless your classes are QObjects, it won't work - but don't despair, Qt 5.5 to the rescue (read on). The browser seems to use a QTreeView and provides an adapter model that exposes the QObject property system. So, it leverages Qt's type and delegate system.
In Qt 5.5, there is a general purpose property system, known as gadgets, that can be used on any class, as long as there is a QMetaObject describing that class. By adding the Q_GADGET macro to a class deriving from the subject class, and describing the properties using Q_PROPERTY macro, you can leverage moc and the gadget system to access your unmodified types' properties.
The only reason you'd do that is to require minimal changes to the ObjectPropertyBrowser system. You don't want the ObjectDynamicPropertyBrowser, since it works on dynamic properties, and your objects don't have any. They have static properties, given through Q_PROPERTY macros and code generated by moc.
So, you'll proceed as you would for implementing your own type support for QVariant and views in general. You also need Qt 5.5, since you need gadget support for it to work. A solution for Qt 5.4 and below requires a different approach and might be less cumbersome to implement in another way.
See this answer for a reference on using gadget property system for object serialization, it's fundamentally what the property browser would do, sans the serialization proper of course.
There are three steps. First, you need to address simple custom types that don't have a structure, but represent a single value (such as a date, or time, or geographic position, etc.), or a collection of simple values (such as a matrix).
Ensure that QVariant can carry the simple types. Add the Q_DECLARE_METATYPE macro right after the type's definition in an interface (header file).
Implement delegates for the types. For types with table structure, such as a matrix, you can leverage QTableView and provide an adaptor model that exposes the type's contents as a table model.
Secondly, you get to your complex types that have internal structure:
Create a wrapper class that derives from the complex type, declares all properties using Q_PROPERTY, and has the Q_GADGET macro (not Q_OBJECT since they are not QObjects). Such class should not have any members of its own. Its only methods should be optional property accessors. The Q_GADGET macro adds the static (class) member staticMetaObject.
The underlying type can be static_cast to the wrapper class if needed, but that's normally not necessary.
At this point, any class that you wrote a wrapper for is accessible to the QMetaProperty system directly, without casting! You'd use the wrapper's staticMetaObject for its static metaobject, but the QMetaProperty readOnGadget and writeOnGadget will take the pointers to the base class directly.
Thirdly, since ObjectPropertyBrowser most likely doesn't implement the support for gadgets in Qt 5.5, as that's quite new, you'll have to modify it to provide such support. The changes will be minimal and have to do with using QMetaProperty::readOnGadget and QMetaProperty::writeOnGadget instead of QMetaProperty::read and QMetaProperty::write. See the serialization answer for comparison between the two.
I've been looking at some related threads but still don't find anything that answers the following question.
Let's say I have a hierarchy of classes (e.g. Widgets, HTML element) that form a tree structure. When I walk through the tree or look for a concrete element based on its ID I get a pointer to the base class (the tree algorithms only know about the base class).
Then, based on the type (the base class has a field that identifies the type) I perform a dynamic_cast in order to get a pointer to the concrete type. I've been thinking about ways to avoid this. The only thing that comes to my mind is the visitor pattern. But don't like very much this pattern.
Are there other ways/patterns to search/iterate nodes and get a pointer to the concrete class without using RTTI nor the visitor pattern?
Your approach doesn't sound like a good idea. Mostly because you have to do all the considerations before the runtime.
What you want to do is basically have the specific properties of a object listed and accessible. With dynamic casting this is possible but hardly elegant - since you have to write a trainload of switches and hardcode each and every possibility in advance so you can use it at runtime.
The solution I'd recommend as usual is the Qt framework. You can list the properties for each object at runtime, access a specific property by its name string or index and even attach properties during the runtime that don't exist in the code. And all this is type agnostic, you don't need to know an object's type to know its properties, and lastly - Qt offers a significantly faster qobject_cast for QObject derived classes instead of dynamic_cast.
The meta system allows you to know the class name, the base class name, methods, enums, constructors and pretty much everything, so besides properties, it is a good source for accessing all the functionality, available to an instance.
It really depends on the implementation of the visitor pattern. Using dynamic_cast<> is one way, another might be to use a handcrafted RTTI by defining a virtual GetType() function which can be implemented in all the subclasses. Depending on the result of that function you can do different things.
I'm creating a C++ object serialization library. This is more towards self-learning and enhancements & I don't want to use off-the-shelf library like boost or google protocol buf.
Please share your experience or comments on good ways to go about it (like creating some encoding with tag-value etc).
I would like to start by supporting PODs followed by support to non-linear DSs.
Thanks
PS: HNY2012
If you need serialization for inter process communication, then I suggest to use some interface language (IDL or ASN.1) for defining interfaces.
So it will be easier to make support for other languages (than C++) too. And also, it will be easier to implement code/stub generator.
I have been working on something similar for the last few months. I couldn't use Boost because the task was to serialize a bunch of existing classes (huge existing codebase) and it was inappropriate to have the classes inherit from the interface which had the serialize() virtual function (we did not want multiple inheritance).
The approach taken had the following salient features:
Create a helper class for each existing class, designated with the task of serializing that particular class, and make the helper class a friend of the class being serialized. This avoids introduction of inheritance in the class being serialized, and also allows the helper class access to private variables.
Have each of the helper classes (let's call them 'serializers') register themselves into a global map. Each serializer class implements a clone() virtual function ('prototype' pattern), which allows one to retrieve a pointer to a serializer, given the name of the class, from this map. The name is obtained by using compiler-specific RTTI information. The registration into the global map is taken care of by instantiating static pointers and 'new'ing them, since static variables get created before the program starts.
A special stream object was created (derived from std::fstream), that contained template functions to serialize non-pointer, pointer, and STL data types. The stream object could only be opened in read-only or write-only modes (by design), so the same serialize() function could be used to either read from the file or write into the file, depending on the mode in which the stream was opened. Thus, there is no chance of any mismatch in the order of reading versus writing of the class members.
For every object being saved or restored, a unique tag (integer) was created based on the address of the variable and stored in a map. If the same address occurred again, only the tag was saved, not the deep-copied object itself. Thus, each object was deep copied only once into the file.
A page on the web captures some of these ideas shared above: http://www.cs.sjsu.edu/~pearce/modules/lectures/cpp/Serialization.htm. Hope that helps.
I wrote an article some years ago. Code and tools can be obsolete, but concepts can remain the same.
May be this can help you.