Sometimes I have a problem and see 3 ways of implementing the solution. I want to know when to use which of these 3 different implementations. Below there are some exsamples, to see what I mean. I also wrote some pros/kontras which I think is correct. If something seems to be wrong, then please tell me and I'll change that.
void* example:
void method(void* value)
{
//save value as member
}
pro void*:
void* can save every type and you don't have to use templates (in headers).
kontra void*:
-when you have a list of void* you can store in index[1] another type than in index[2] which is critical, because you don't know which type it is. But with dynamic_cast you can check if you can cast it to the type or not.
-when you have a void* list with entities of the same class which have 2 variables, you can not sort by variable1 / variable2 without casting it back to the original class.
Extension exsample:
Creating a new class and extent it on another class:
class CTestClass
{
void Method1();
};
class CTest2 : CTestClass
{
//use somehow the method
};
std::vector<CTestClass> list;
pro Extension:
this way of implementing a class can be usefull, if you need a method which is in every object you need. For example you want to sort by a variable. In such a method you can make the compare.
kontra Extension:
much effort
exsample template:
template <class T>
class CTest
{
//do some stuff
};
pro template:
in a template list, you can not add different types at the same time.
kontra template:
when you have a template list of type T and T has for exsample 2 variables. You can not say: sort by variable1 or variable2 because you can not get into the class T.
As far as I know: you have to implement the template into the header file, which is ugly to see.
I hope everyone understands what I mean.
Is void* a good way to program?
Can I write templates also in .cpp files?
What do you think when to use which of this techniques? Is there some kind of rule?
The statement below is incorrect
pro void*:
void* can save every type and you don't have to use templates (in
headers).
Templates haver their closest equivalent in cross macros and not in void pointers, but exist for a different set of purposes than the mere polymorphism afforded by void pointers. Using void pointers in no way substitutes templates.
While modern programmers might not recommend about using void pointers, complaining about the (true!) potential dangers afforded, old school C-style code certainly has a use for them and this is the reason they exist. Pairing the benefits gained from void pointers with the tradeoff in performance by the C++ dynamic cast, would simply spoil the choice.
Void pointers just exist to offer limitless flexibility at managing memory when you know what you are doing and should be used only in that case. There is no comparison between them and templates.
A method that takes a void * argument should only exist when:
Case 1: The size of the passed data is known and the argument is considered as raw data. It makes no difference what that data is.
Case 2: The size of the passed data is known and you plan to convert it to a pointer of the appropriate type later (for example by some parsing, enumeration policy, known type, etc) but in order to go through some general purpose functions, libraries, APIs, you must convert it to known-length void* inbetween.
Related
In my code, I have several class, each with different methods. For example:
class A {
public:
int sum(int a, int b);
bool isScalable(double d);
}
class B {
public:
std:string ownerName();
}
My aim is to create a map of all the function names as below
std::map<std::string, FnPtr> myMap;
// Add the newly implemented function to this map
myMap["sum"] = &A::sum;
myMap["isScalable"] = &A::isScalable;
myMap["myMap"] = &B::myMap;
The issue is I am not aware how I can define FnPtr. Can you please help me out.
As comments suggest, it is unlikely you really want to do this.
Assuming that you do, however - perhaps you should reconsider whether C++ is the right language for the task. Another language which has better runtime reflection facility might be more appropriate; perhaps an interpreted language like Python or Perl. Those are typically much more convenient when you need to look up class methods by name at runtime.
If it has to be C++, then perhaps you should relax the class structure somewhat. Use a single class for both A's and B's (lets call it MyCommonObj); and have the class hold a map of strings to function pointers. As for these functions' signatures - It's probably a good idea not to make the member functions, but freestanding ones. In that case, perhaps your function pointer type would be:
using generic_function = std::any (*)(std::vector<std::any>);
That's pretty generic - for storage and for invocation. If you have this map, you can easily look up your function name and pass the arguments. However, you might need to also keep additional information about what type your arguments should be, otherwise you'll always be passing strings. ... which is also an option, I suppose:
using generic_function = std::any (*)(std::vector<std::string>);
Now if the A and B members in your example are really non-static like you listed them, i.e. they use instance fields, then these generic functions must also always take a reference or pointer to an instance of MyCommonObj:
using generic_function = std::any (*)(MyCommonObj&, std::vector<std::string>);
Finally, note that code using this type, and run-time lookup of function names etc - will not be very performant.
If you're not using C++17 and don't have access to std::any, you can either:
Use boost::any from the Boost libraries.
Use an any-emulator library (which exist on GitHub)
Use a union of all the types you actually use, e.g. union {int i; double d;} - but then you'll need to protect yourself against passing values of the wrong type.
This quesiton is composed of a couple parts, the first has to do with the -> operator in a class. Does it take some sort of input (according to the C++ standard)? For example
some_return_type? operator->( long address ) {
cast the address to some sort of pointer and do something with it...
return something?...possibly... maybe not?;
}
So in reality A::SomeMethod() would refer to an address for a function in memory passed to ->. Or
A::someStaticOrNonStaticDataMember would refer to an address for a field?
If so (given that we do not have access to the actual type of the class), or something like this exists, what is it, and can we reconstruct part of a pointer, or align a pointer, (or write a class with an algorithm to do this), for a class based on some information about that class, so that it had an operable -> operator, so one could write:
somePointer->A::SomeMethod();
and have it call A::SomeMethod()? And maybe make context for the memory used in the class?
From the comments it seems you want to control how Compiler handles and generates -> tokens. This is for your bad luck not possible, because Compiler doesn't expose such information, nor is it required by Standard to do so
It is like you are trying to have "dynamic" (the C# type) but in C++, unluckily this is not possible. What could be similiar is wrapping some sort of "Closure collection" addressed by strings (a sort of scripting language) but that would be really heavy and not very nice.
Actually doing what you want with the syntax you showed is not possible.
If the type of an object is not known, then you have that object hided behind a "void *". That means basically that the only way you can use that object is by casting it back to its original type.
Suppose you have a DLL that expose 2 functions (with header files)
// creates an object of given type or null_ptr if no object match
void* getObject(std::string obj_type);
// call a method on that object
void callMethod(void* obj, std::string method_name, void* args, void* returnval);
Actually that solution (even if ugly) allows to call methods on objects that you don't know (it could be a lot better than that.)
But that force you to use void* and strings. That's because how C++ resolve method names (in reality also in C# the "dynamic" type generates behind the scenes reflection code that use strings with method names and is particulary slow)
So something similiar can be achieved with
float fuelLiters = 3.0f;
void * myObj = createObject("SomeCar");
callMethod(myObj,"loadFuel", &fuelLiters, null_ptr);
you probably can make the syntax a little better with templates or some macro, but you'll never be able to do something like
myObj->A::loadFuel(fuelLiters);
What you can do is having the externally loaded class, use the same interfaces of your application, says:
class ICar{
public:
void loadFuel(float liters)=0;
};
In that case you can use a function that cast the opaque object handle to ICar. This is what I already doing in a library I wrote 2 years ago:
So you just need the DLL expose a method for casting the class (downcast)
//if given object is implementing a ICar, the correct pointer is returned, else
// this function will return nullptr (or throw exception if you like more)
void * downcast( typeof(ICar), myObj);
You'll need simply
ICar *myCar = static_cast<ICar>(downcast( typeof(ICar), myObj));
myCar->loadFuel(3.0f);
However note that both the DLL and your application should "know" about what "ICar" is, so they must include the "ICar" header.
doing that is definitely possible, I did it already in 2 different ways, so If you need more details about implementation I'll be happy to show a possible way (given I understood correctly your question).
The arrow operator (->) is a dereference operator that is used exclusively with pointers to objects that have members.
foo->bar() is the same as (*foo).bar()
If you want to overload -> you should also overload *
This is not a question about how they work and declared, this I think is pretty much clear to me. The question is about why to implement this?
I suppose the practical reason is to simplify bunch of other code to relate and declare their variables of base type, to handle objects and their specific methods from many other subclasses?
Could this be done by templating and typechecking, like I do it in Objective C? If so, what is more efficient? I find it confusing to declare object as one class and instantiate it as another, even if it is its child.
SOrry for stupid questions, but I havent done any real projects in C++ yet and since I am active Objective C developer (it is much smaller language thus relying heavily on SDK's functionalities, like OSX, iOS) I need to have clear view on any parallel ways of both cousins.
Yes, this can be done with templates, but then the caller must know what the actual type of the object is (the concrete class) and this increases coupling.
With virtual functions the caller doesn't need to know the actual class - it operates through a pointer to a base class, so you can compile the client once and the implementor can change the actual implementation as much as it wants and the client doesn't have to know about that as long as the interface is unchanged.
Virtual functions implement polymorphism. I don't know Obj-C, so I cannot compare both, but the motivating use case is that you can use derived objects in place of base objects and the code will work. If you have a compiled and working function foo that operates on a reference to base you need not modify it to have it work with an instance of derived.
You could do that (assuming that you had runtime type information) by obtaining the real type of the argument and then dispatching directly to the appropriate function with a switch of shorts, but that would require either manually modifying the switch for each new type (high maintenance cost) or having reflection (unavailable in C++) to obtain the method pointer. Even then, after obtaining a method pointer you would have to call it, which is as expensive as the virtual call.
As to the cost associated to a virtual call, basically (in all implementations with a virtual method table) a call to a virtual function foo applied on object o: o.foo() is translated to o.vptr[ 3 ](), where 3 is the position of foo in the virtual table, and that is a compile time constant. This basically is a double indirection:
From the object o obtain the pointer to the vtable, index that table to obtain the pointer to the function and then call. The extra cost compared with a direct non-polymorphic call is just the table lookup. (In fact there can be other hidden costs when using multiple inheritance, as the implicit this pointer might have to be shifted), but the cost of the virtual dispatch is very small.
I don't know the first thing about Objective-C, but here's why you want to "declare an object as one class and instantiate it as another": the Liskov Substitution Principle.
Since a PDF is a document, and an OpenOffice.org document is a document, and a Word Document is a document, it's quite natural to write
Document *d;
if (ends_with(filename, ".pdf"))
d = new PdfDocument(filename);
else if (ends_with(filename, ".doc"))
d = new WordDocument(filename);
else
// you get the point
d->print();
Now, for this to work, print would have to be virtual, or be implemented using virtual functions, or be implemented using a crude hack that reinvents the virtual wheel. The program need to know at runtime which of various print methods to apply.
Templating solves a different problem, where you determine at compile time which of the various containers you're going to use (for example) when you want to store a bunch of elements. If you operate on those containers with template functions, then you don't need to rewrite them when you switch containers, or add another container to your program.
A virtual function is important in inheritance. Think of an example where you have a CMonster class and then a CRaidBoss and CBoss class that inherit from CMonster.
Both need to be drawn. A CMonster has a Draw() function, but the way a CRaidBoss and a CBoss are drawn is different. Thus, the implementation is left to them by utilizing the virtual function Draw.
Well, the idea is simply to allow the compiler to perform checks for you.
It's like a lot of features : ways to hide what you don't want to have to do yourself. That's abstraction.
Inheritance, interfaces, etc. allow you to provide an interface to the compiler for the implementation code to match.
If you didn't have the virtual function mecanism, you would have to write :
class A
{
void do_something();
};
class B : public A
{
void do_something(); // this one "hide" the A::do_something(), it replace it.
};
void DoSomething( A* object )
{
// calling object->do_something will ALWAYS call A::do_something()
// that's not what you want if object is B...
// so we have to check manually:
B* b_object = dynamic_cast<B*>( object );
if( b_object != NULL ) // ok it's a b object, call B::do_something();
{
b_object->do_something()
}
else
{
object->do_something(); // that's a A, call A::do_something();
}
}
Here there are several problems :
you have to write this for each function redefined in a class hierarchy.
you have one additional if for each child class.
you have to touch this function again each time you add a definition to the whole hierarcy.
it's visible code, you can get it wrong easily, each time
So, marking functions virtual does this correctly in an implicit way, rerouting automatically, in a dynamic way, the function call to the correct implementation, depending on the final type of the object.
You dont' have to write any logic so you can't get errors in this code and have an additional thing to worry about.
It's the kind of thing you don't want to bother with as it can be done by the compiler/runtime.
The use of templates is also technically known as polymorphism from theorists. Yep, both are valid approach to the problem. The implementation technics employed will explain better or worse performance for them.
For example, Java implements templates, but through template erasure. This means that it is only apparently using templates, under the surface is plain old polymorphism.
C++ has very powerful templates. The use of templates makes code quicker, though each use of a template instantiates it for the given type. This means that, if you use an std::vector for ints, doubles and strings, you'll have three different vector classes: this means that the size of the executable will suffer.
I inherited a big application that was originally written in C (but in the mean time a lot of C++ was also added to it). Because of historical reasons, the application contains a lot of void-pointers. Before you start to choke, let me explain why this was done.
The application contains many different data structures, but they are stored in 'generic' containers. Nowadays I would use templated STL containers for it, or I would give all data structures a common base class, so that the container can store pointers to the base class, but in the [good?] old C days, the only solution was to cast the struct-pointer to a void-pointer.
Additionally, there is a lot of code that works on these void-pointers, and uses very strange C constructions to emulate polymorphism in C.
I am now reworking the application, and trying to get rid of the void-pointers. Adding a common base-class to all the data structures isn't that hard (few days of work), but the problem is that the code is full of constructions like shown below.
This is an example of how data is stored:
void storeData (int datatype, void *data); // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);
This is an example of how data is fetched again:
Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);
I actually want to replace all the void-pointers with some smart-pointer (reference-counted), but I can't find a trick to automate (or at least) help me to get rid of all the casts to and from void-pointers.
Any tips on how to find, replace, or interact in any possible way with these conversions?
I actually want to replace all the
void-pointers with some smart-pointer
(reference-counted), but I can't find
a trick to automate (or at least) help
me to get rid of all the casts to and
from void-pointers.
Such automated refactoring bears many risks.
Otherwise, sometimes I like to play tricks by making out of such void* functions the template functions. That:
void storeData (int datatype, void *data);
becomes:
template <class T>
void storeData (int datatype, T *data);
At first implement template by simply wrapping the original (renamed) function and converting the types. That might allow you to see potential problems - already by simply compiling the code.
You probably don't need to get rid of the casts to use shared pointers.
storeData(TYPE_CUSTOMER, myCustomer1->get());
shared_ptr<Customer> myCustomer2(reinterpret_cast<Customer*>fetchData(TYPE_CUSTOMER, "???");
Of course, this assumes that you don't expect to share the same pointer across calls to store/fetch. In other words, myCustomer1 and myCustomer2 don't share the same pointer.
Apparently, there is no automated way/trick to convert or find all uses of void-pointers. I'll have to use manual labor to find all void-pointers, in combination with PC-Lint that will give errors whenever there is an incorrect conversion.
Case closed.
I have to fix a typical memory leak, Problem is like that :
typedef std::map<unsigned long,Response> mapType;
class Response
{
public:
void *dataPtr;
unsigned long tag;
}
class anyClass
{
public::
DataType x;
}
From client i am getting a map of Type mapType , Which has Response object as map->second , As Response object contain a void Pointer.
Please note : Response Class do not know what type of data has been set to void pointer, Also i can't modify Response class to do so , As it is a legacy code and has a great impact :(
Now using map->first ,that i call as Tag,
Using this tag at run time using this tag i come to know about a class anyClass.
Now Response::dataPtr is smae as anyClass::DataType
But:
as class anyClass is one out of N type, So anyClass::DataType differs for each class which i come to know only at runtime.
Please guide me how i can cast a void pointer to type same to anyClass::DataType and can free it
Given that you mention "legacy" code, but may have some freedom to modify, I would likely suggest that whatever interface provided you the map be extended to include a free-ing function.
Then it could apply the same type logic as when it created the object in the first place.
If that is impossible, then you will likely end up with a case statement and some re-interpret casts like the following pseudo-code:
switch (type ) {
case Type1:
delete reinterpret_cast<Type1Class*>(ptr);
break;
case Type2:
...
Good Luck
First, I don't know why do you need to cast these pointers to their original type if it is a memory leak issue. You can simply delete the void* pointer anywhere.
Second, you can convert the pointer to a specific type with a simple conditional statement to some specific type compared to the tag, but you need to have the specific code for that pointer in the given context, so in this sense there is not enough information here to solve the problem.
However, if you have a certain behaviour for your responses, call it 'process', you can use inheritance with virtual function to bind the desired behaviour to your object. This is basically the definition of the virtual methods, so use them, even if you need to refactor the old code for this. If there is a problem with the object disposing then it is a matter of a virtual destructor, so the base class should define a virtual dtor, and the using the dynamic_cast(ptr) gives you some type safety at the conversion.
In this way, you don't need the 'tag' member, unless you would like to this by hand with a big 'switch' statement. In this case I can suggest to use crc calculation from the typeid(AnyClass).name() in the tag member.
-- EDIT:
There is an other way to store these object without having this issue, I would say a boost::any or similar functionality could solve your problem. If you are storing the data's in a boost any instead of void* pointers you can change the legacy code with a minimal impact. If you delete an entry from the map, it will remove the boost::any's inner value. That should do the trick.
If your tags are sequential you can build smth. like an array with either function objects or function pointers of their handlers:
template<class T>
void deleteType(void* p)
{
delete reinterpret_cast<T*>(p);
}
typedef void (deletePtr)(void*);
deletePtr handlers_[] =
{ &deleteType<int> //means: accessed by tag with value 0
, &deleteType< vector<int> > // tag with value 1
, ...
};
//somewhere later:
handlers_[response->tag](response->dataPtr);
This solution requires you to know all types which are possibly stored in response.
If tags are not sequential, you will need to use a map or smth. similar, which involves non-constant complexity.
Hope that helps,
Ovanes
P.S. But if you decide to change the response take a look at boost::variant. Which is exactly what you need, if you were allowed to program generically ;)