How to generate C++ Dynamic Objects names? - c++

I'd like to generate a number of objects (in C++) based on the amount/number the user enters.
Now I've somewhere heard that it has to be done using pointer tricks, creating a pointer to an array of the Object type required, and then dynamically increasing the size of array ( at runtime ).
Isn't there a workaround of directly using names like
Object1, Object2..... ObjectX
instead of having
Classname *Object[]
and then using the array index to get the object ?
In either case, it'd be great if someone could clarify on the issue.
Thanks !

If you want dynamically-sized array, then use std::vector. You won't be able to resize a built-in array.
If you want to be able to get an object by string name, then you should use std::map, it has an indexer:
std::map<string, Classname> myMap;
myMap["Object1"] = Classname();
Classname newClassname = myMap["Object1"];

So far no-one has explained why your thinking is flawed. C++ is a compiled language, and it goes to great lengths to turn the source program into efficient machine code. For this reason, the names you give variables are available to the program only at compile time, when you turn it from source into an executable file. Afterwards, when you want to create objects dynamically, those kinds of information are no longer available. The program only knows about the machine addresses where operands to machine instructions are located.

No, there isn't. Moreover, you don't need to; use std::vector.

When I began programming 9 years ago I asked myself the same question. The answer is: you can't.
You can indeed use an array and resize it dynamically, however using an stl vector is much easier (once you learn how to use it).

You can not do that because C++ doesn't have an "environment" (reflection) where variables (and metadata) can reside. Moreover, in C++ all variable names are vanished when the code is compiled.
A way to achieve the effect you want is to use a Map where the keys are strings.

Related

how to keep unknown variables that passed by my class user

I need a kind of variable in c++ to save all objects and ... like "Object" in c# anyway I want to pass every kind of vars in it . (unknown variables )
thanks.
Check out boost::any and boost::variant from the Boost library.
That said, usually a need to circumvent the type system is an indication of something wrong. Instead of using one of the aforementioned solutions, I recommend thinking hard about what constraints put you in this direction.

How to create dynamic object based on user input or file without schema in C++

I have good command over c++ language.I am interested in creating code which generates the object dynamically for which no schema has already been defined in code.First of all, is it possible to do so in c++? If yes, please anyone would guide me how to do it?
For example,
<name>android</name>
<count>5</count>
<version>4.4.4</version>
If this is given in file(.xml), the automatic object should be created and I should be able to access it.
TempObj.name, TempObj.count and TempObj.version etc..
No, you cannot do this at runtime in C++. Types have to be known at compile time in C++.
You can do code generation, i.e. read XML, generate C++, and compile. Or you can use a slightly different syntax (and much slower performance) to access the methods, basically:
typedef std::map<std::string, std::string> Object;
Object obj = load("whatever.xml");
assert(obj["name"] == "android");
But to do exactly what you've asked will require a different language. Tons of choices: Python and Lua are two that easily integrate with a C++ application directly, if you want that.
Using a hash table would solve your problem. in C++, the STL (standard template library) provides std::unordered_map<>
You should use that to solve your problem.
std::unordered_map<std::string, std::string> hm
The API is nice, where you can insert and change elements by using the [] operator.
hm["name"] = "android"
hm["count"] = "5";
hm["version"] = "4.4.4";
If you need dynamic types, you could probably use templates.
You may be wondering why you would use an ordered or an unordered map in C++. With an ordered map, all elements are able to iterated in the order they were inserted, whereas an unordered map the order in which you will access them is random based on the hashed value.

C++: use of “().” and “()[].”

I am trying to understand the programming of Siemens scanner using C++ and given that my C++ skills are limited, I am having problems in understanding many parts of the code provided by the vendor.
Problem 1
For instance, the code uses reference (rMrProt) to object MrProt and notations (such as the use of use of (). and ()[].) are very confusing to me.
For instance:
ImageSamples = rMrProt.kSpace().baseResolution()
ImageSize = rMrProt.sliceSeries()[0].readoutFOV()
Some explanation of these statements would be appreciated.
All information regarding object MrProt are in “MrProt.h”, “MrProt.dll”, “MrProt.lib”. All these files have been shared at:
https://docs.google.com/open?id=0B0Ah9soYnrlIYWZkNDU2M2EtYTNmNC00YTc5LTllMzItYzIyMWU4M2ZhY2Fi
Problem 2
Also, I have been trying to read MrProt.dll and MrProt.lib without any success. Only now, I came to know of dumpbin. Any help would be appreciated.
Problem 3
Another confusion that I have is related to some part of MrProt.h itself. There is a statement in MrProt.h:
class __IMP_EXP MrProt: public MrProtocolData::MrProtDataDelegate
{
typedef MrProtocolData::MrProtDataDelegate BasicImplementation;
public:
MrProt();
MrProt(const MrProt& rSource);
…
….
}
Here, __IMP_EXP, I guess that it’s some compiler specific stuff.. some decoration etc. But, I still have no idea what to make of this.
Problem 1.
rMrProt.sliceSeries()[0].readoutFOV()
means
Take rMrProt's sliceSeries member and call that. Apparently, it returns an array-like object, something that can be indexed.
From the result, take the first element ([0]). That's some kind of object.
On that element/object, call readoutFOV.
Problem 2. You're not really supposed to read binary files. There should be documentation with them.
1)
ImageSamples = rMrProt.kSpace().baseResolution()
This is just method chaining. You call the method kSpace() on rMrPrto which returns an object, and you call baseResolution() on that object.
2) Those are binary files. What would you expect to see? To read them you'd have to be an expert in asm or at least know some low-level concepts.
3) __IMP_EXP is a common type of directive that tells the compiler that the class is either exported or imported.
It expands to _declspec(dllimport) or _declspec(dllexport), depending on whether the definition of the class is in the current module or another module.
identifier() is a method/function call
identifier[i] returns the i'th element in an array.
identifier()[i] returns the i'th element of the array returned by identifier()
I can only help on problem 1:
if the return value of rMrProt.kSpace() is a struct. instead of saving it to a struct and then access it's member you can directly access a member of his with rMrProt.kSpace().MemberName
same for rMrProt.sliceSeries() which I guess is returning an array. so rMrProt.sliceSeries()[0] will access the first value in the returning array.

Ways to use variable as object name in c/c++

Just out of curiosity: is there a way to use variable as object name in c++?
something along the lines:
char a[] = "testme\0";
*a *vr = new *a();
If you were to write a c/c++ compiler how would you go about to implement such a thing?
I know they implemented this feature in zend engine but to lazy to look it up.
Maybe some of you guys can enlight me :)
In case what you are looking for is something like this
<?php
$className = "ClassName";
$instance = new $className();
?>
That's simply not possible in C++. This fails for many reasons, one of them that C++ at runtime doesn't know much about names of classes anymore (only in debug mode) If somebody wanted to write a compiler that would allow something like this, it would be necessary to keep a lot of information that a C++ compiler only needs during compilation and linking. Changing this would create a new language.
If you want to dynamically create classes depending on information only available at runtime, in C++ you would most likely use some of the Creational Design Patterns.
Edit:
PHP is one language, C++ is a very different one. 16M may not be that much nowadays, for a C++ programmer where some programs are in the k range, it's a whole world. Nobody wants to ship a complete compiler with his C++ app to be able to get all the dynamic features (that btw PHP too implements only in a limited way as far as I know, if you want really dynamic runtime code creation, have a look at Ruby or Python). C++ has (as all languages) a certain philosophy and creating objects by name in a string doesn't fit very well with it. This feature alone is quite useless anyway and would by no means justify the overhead necessary to implement it. This could most likely be done without adding runtime compilation, but even the extra kilobytes necessary to store the names alone make no sense in the C++ world. And C++ is strictly typed and this functionality would have to make sure, that type checking doesn't break.
In C and C++, identifier names do not have the same meaning they do in PHP.
PHP is a dynamic language, and (at least conceptually) runs in an interpreted context. Identifier names are present at run time, they can be inspected through PHP's reflection features, you can use strings to refer to functions, variables, globals, and object properties by name, etc. PHP identifiers are actual semantic entities.
In C++, identifiers are lost at run time (again, conceptually speaking). You use them in your source code to identify variables, functions, classes, etc., but the compiler translates them into memory addresses or literal values, or even optimizes them away completely. Identifier names are not generally present in the compiled binary (unless you instructed the compiler to include debug symbols), and there is no way to inspect them at run-time. Even with RTTI, the best you can get is an arbitrary number to identify a type; you can compare them for equality, but you cannot get the name back.
Consequently, if you want to translate strings into identifier names at run-time in C++, you have to perform the mapping manually. std::map can be a great help for this - you hand it a string, and it gives you a value. This doesn't work directly for class names; for these, you need to implement some sort of factory method. A nice solution is to have one wrapper function for each type, and then a std::map that maps class names to the corresponding wrappers. Something like:
map<string, FoobarFactoryMethod> factory_map;
Foobar* FooFactory() { return new Foo(); }
Foobar* BarFactory() { return new Bar(); }
Foobar* BazFactory() { return new Baz(); }
void fill_map() {
factory_map["Foo"] = FooFactory;
factory_map["Bar"] = BarFactory;
factory_map["Baz"] = BazFactory;
}
// and then later:
Foobar* f = factory_map[classname]();
Why do you even want to have this feature? You are most likely misusing OOP. Whenever my needs ran into hard language barriers like this I ended up doing one of the following:
Rethink your solution to the problem so it fits OOP better
Create a DSL for your problem (domain specific language)
Create a code generator for this part of your problem
Pick a language that fits your problem better
A combination of the above
I would think that what you want to do would be best accomplished using interfaces and a factory pattern.

Arrays of strings in Managed C++

I'm trying to write an application in Managed C++, but I cannot work out how to declare an array of strings.
String^ linet[];
throws an error
'System::String ^' : a native array cannot contain this managed type
So I suppose there's a different way to do this for managed data types. What exactly is it?
Do you really mean Managed C++? Not C++/CLI?
Assuming you're actually using C++/CLI (because of the error message you posted), there are two ways to do this:
array<String^>^ managedArray = gcnew array<String^>(10);
will create a managed array, i.e. the same type as string[] in C#.
gcroot<String^>[] unmanagedArray;
will create an unmanaged C++ array (I've never actually tried this with arrays - it works well with stl containers, so it should work here, too).
http://www.codeproject.com/KB/mcpp/cppcliarrays.aspx
That should have all the answers you need :)
When working with Managed C++ (aka. C++/CLI aka. C++/CLR) you need to consider your variable types in everything you do. Any "managed" type (basically, everything that derives from System::Object) can only be used in a managed context. A standard C++ array basically creates a fixed-size memory-block on the heap, with sizeof(type) x NumberOfItems bytes, and then iterates through this. A managed type can not be guarenteed to stay the same place on the heap as it originally was, which is why you can't do that :)
You use a collection class from .Net. For example:
List<String^>^ dinosaurs = gcnew List<String^>();