How to pass values in Qt? - c++

I am doing the NFC project. In this I need to detect the tag and read the tag contents from the NFC tag and i need to send the tag id to the PHP server. From the server side i will get the response as {tagId&tagcontent}. After this i need to extract the tagId and tagcontents. Till this i have finished and working fine. Now my problem is to pass the value to another class. As soon as i get the SUCCESS response from server i need to pass the extracted values to another class. How can i do that. I am new to Qt programming. Please help me.

You can pass the parameters as key value pairs i.e. use a QHash or a QVector for this purpose.
Moreover, if you want the information ot be too specific, you can define a custom C++ class, containing values for the response fields and pass the reference from your 1st class to the other class.
Parameter passing in Qt is similar to C++.
Your QStringList, QVector or QHash all are just classes.
You can pass objects of these class as any other custom class.
For example:
In your target class (say T):
void getResponseHeader(QHash<QString,QString> x);
In your calling class(say C):
T *t = new T(); //or whatever instance you have
t->getResponseHeader(myParsedResponse);
More specifically, you can pass parameters inC++ either by value or by reference.
For passing objects, it is better to pass them via reference.
Passing by value means that a copy of the object is made on the callee’s stack and altering the object means altering a local copy so the caller’s object is unchanged when the function returns. Passing by reference means that the address of the object is send (a reference holds an address but behaves like an object) so that the callee can directly alter the original object.
Have a look at this thread for What's the difference between passing by reference vs. passing by value?
A nice explanation with examples is provided on codeforum at http://www.codeguru.com/forum/showthread.php?t=343473

Related

Taking object as input from User in C++

Actually, I want to pass an object to function by taking input from User. There are many objects and I want user to tell which object to pass. One way that I can think of is by using if/else-if statements (e.g if user says 1(int) then it means object-1). But is there any direct method by which I can directly take object as input. So I can pass it to function without using if/else-if statements.
You cannot have a user input an object directly out-of-the-box, but you can certainly write code to obtain that result (for example by implementing deserialization and receiving a JSON representation of the object).
However, if I understood your question correctly, you have a predefined set of objects with known integer keys. In that case, the most straightforward way is to store these objects in a container, such as std::map<int, YourObject> (or an std::vector<YourObject> if your keys are easily mappable to [0;N)). Once you've had the user input the key, you can then lookup into the container to retrieve the corresponding object via the container's at() member function.

wxWidgets wxFileSystemHandler::OpenFile() never gets called

I extended the class wxFileSystemHandler to handle special protocols I use in my application. My implementation of wxFileSystemHandler::CanOpen() is called, recognizes the protocol and returns TRUE. But my implementation of wxFileSystemHandler::OpenFile() never gets called. I inspected the wxWidgets code and saw that the CanOpen() member function is called by the pointer that I registered. But when a call to OpenFile() is made they pass the pointer to a wxFileSystem::MakeLocal() member function that tries to get another pointer inside a hash map that, obviously, is not my instance.
Someone got a problem like this before?
Not sure what exactly are you doing, i.e. when do you expect your handler to be called, but in any case MakeLocal() is supposed to create a new instance of the same class if you mark the object as being dynamically creatable using wxRTTI macros and use the object as given otherwise. So if you really need the same object to be reused, you probably need to use wxDECLARE_ABSTRACT_CLASS() in its class. But OTOH why is it a problem to make a new instance?

Callback method cannot access member variables or instance

I am writing for a simulation that uses an old 3D model file format (Carbon Graphics' GEO, if you're interested), and the way the OpenSceneGraph plugin for this model format updates its internal variables is by you registering a callback method for the model to call when it's time to update its values. The callback has the simulation time, the variable name, and its current value. You are to return back the new value for that variable.
So, in my code, I set the callback as follows:
headerNode->setUserUpdate(&FlightDriver::updateGeoVariable);
The class headerNode belongs to has the following variable:
double (* uvarupdate)(const double t, const double val, const std::string name);
Every interval, it will call uvarupdate which I have set to:
updateGeoVariable(const double time, const double val, const std::string name)
{
return flightData->getValue(name);
}
for each variable inside the model, one at a time. I can't make the method or the flightData member static, as they need to be unique per instance.
I have a hunch that this callback is possibly being called from C code, because when I break, it seems to have no knowledge that it is inside a class, and if I change the signature, the same three values get passed and shoehorned into whatever parameters are first.
However, I really need access to the members of the class, to avoid a really dirty kludge. Since the class itself is what drives a model in the 3D world, having 2 or more of these means that I get callbacks that say: "234, pitch, 90" and I have no way of knowing which model's variable that data belongs to.
I could possibly recompile the DLL (as it is an OSG plugin) to take additionally a pointer to that instance, or an id, or something, and return it in the callback, but I'd really like to avoid that if possible.
I've read about thunking, but it looks like that and most other ideas require access to the code that creates the callback. Any ideas?
You need to pass a pointer to method, but the uvarupdate is pointer to function, these are different types. Pointer to a method contains implicit pointer to this of an instance, it doesn't fit into function-pointer. You need to pass this in some another way.
If you do not change signature of the callback, you have to calculate an instance (this) somehow. If it can be determined from name parameter, well, it's easy. Another way is to create a trampoline for each instance you have. If there are only few instances, you can write a separate trampoline function for each instance. Creating trampolines dynamically (in run-time) is tricky and non-portable: in fact, you need to write some machine instructions into RAM so that they call your method with the correct this parameter. But that's also possible, that's what some libraries do (e.g. VCL in Delphi).

Member pointers or reference arguments?

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.

Create an instance from a static method

let's say I want my users to use only one class, say SpecialData.
Now, this data class would have many methods, and depending on the type of data, the methods do different things, internally, but return externally similar results. Therefore my wanting to have one "public" class and other "private", child classes that would change the behavior of methods, etc...
It would be amazingly more simple for some types of data that need to be built to do something like this:
SpecialData& sm = SpecialData::new_supermatrix();
and new_supermatrix() would return a SuperMatrix instance, which inherits from most behaviors of SpecialData.
my header:
static SpecialData& new_supermatrix();
my cpp:
SpecialData& SpecialData::new_supermatrix()(){
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
}
The problem is, I get this error, which is probably logical due to the circumstances:
invalid initialization of non-const reference of type ‘SpecialData&’ from a temporary of type ‘SpecialData’
So, any ideas?
Well, you've got three choices:
a) You want to have only one instance of SuperMatrix anyway. Then go for the static function member route as has already been suggested.
b) You want to create multiple instances. Then you have to return a pointer instead of references and create the objects with with new (i.e. return new SuperMatrix(...).
c) As an alternative to option b, you can also return merely an object, i.e.
SpecialData SpecialData::new_supermatrix()(){
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
}
However, this requires a (deep-)copy operator (the default one won't suffice more often than not), and it means that the object is created on the stack, then copied and that copy is being returned. The good thing is, this won't leak memory if you don't actually receive the result into a variable. The bad thing is, if the object is very large, this can be very memory- and time-consuming.
Whatever you are going to do with it, these solutions are mutually exclusive, both technically and logically. ;)
Simple answer - you can't use references like that. Your new_supermatrix function returns a nameless temporary value which you try to bind to a non-const reference - C++ only allows such values to be bound to const references. If you want to write functions like this, you need to make them return a pointer to a dynamically allocated object, or stick with returning a value, but assign the return value to another value in the calling code.
This code has several problems. First of all, you probably want to use pointers here instead of references. Returning a reference to an object created on the stack like you do in your new_supermatrix will lead to a crash almost immediately. It needs to be allocated with new and passed back as a pointer if that's what you want but I'm not exactly sure what you're trying to do. But anyway, this is what's causing your error, you're returning a reference to a temporary variable.
You need to actually use the new operator. The creation you get by return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); allocates the object on the stack, which is cleaned up when the function returns (which it is doing in the same line). Using new causes it to be allocated on the heap.
In your method, you can use a static:
SpecialData& SpecialData::new_supermatrix()(){
static SuperMatrix supermatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);
return supermatrix;
}
You must not return a reference to a temporary/local object.
This and many other common errors-to-be-avoided are explained in Meyers' book, Effective C++.
You're returning a reference to a temporary object, which is bad news, since once your method exits, the object doesn't exist anymore.
Read up on creational design patterns. The one that looks closest to what you want to do is the Factory Method pattern.