Casting from any - c++

I'm packing some classes into ptr_map with any typed value.
class EventManager
{
ptr_map<string, any> mSomeMap;
public:
typedef signals2::signal<void (int someSignature)> KeyEvent;
EventManager()
{
mSomeMap["KeyPressed"] = new any(new KeyEvent());
}
};
Now I want to restore my signal object from any. Here is a special function for this:
template<typename EventType>
EventType *get(const string &signalName)
{
try {
return any_cast<EventType*>(mSomeMap[signalName]);
} catch(bad_any_cast &e){}
}
As you could remember, the boost's signals are noncopyable so I can store only pointers and my function should return pointers too.
Now sample usage:
evManager.get<EventManager::KeyEvent>("KeyPressed");
Here I get segfault. I checked the types of each objects in the get function:
typeid(EventType).name()
→ N5boost8signals26signalIFvRN2sf5Event8KeyEventEENS0_19optional_last_valueIvEEiSt4lessIiENS_8functionIS6_EENSB_IFvRKNS0_10connectionES5_EEENS0_5mutexEEE
mSignalAssociation[signalName].type().name()
→ N10__cxxabiv119__pointer_type_infoE
What's wrong is there? The segfault at line with casting. Any object should consist of inserted type or not? Why it doesn't want to cast.

ptr_map<string, any> mSomeMap;
...
mSomeMap["KeyPressed"] = new any(new KeyEvent());
Do you realize what happens here? First, you create a KeyEvent object dynamically which results in a pointer. Then this pointer is wrapped into an any-object which is also dynamically created which also returns a pointer which is then again wrapped in another any object implicitly by the assignment.
Also, for extracting the right value from an any object you need to know the exact type. So, for example, if you pack a Derived-pointer into an any object, you won't be able to access it via an any_cast<Base*> because Base* and Derived* are different types in terms of the std::type_info objects boost::any uses to keep track of types. boost::any just doesn't know how to convert the packed Derived-pointer to your Base-pointer.
Is there a special reason why you wrap so many things in any-objects including pointers to any-objects? Wouldn't it make sense to use something like a ptr_map<KeyType,BaseType>? You know that if you pack a pointer into an any object that you still need to delete the pointees yourself, right? The any-object is not going to do this for you.

Related

Unhandled exception - c++ program stops on cast

I have several structs:
struct Token
{
//some content
}
Then follows a bunch of structs that inherit from Token:
struct A : public Token{
//Stuff
}
.
.
.
struct Z : public Token{
//Other stuff
}
I have a vector std::vector filled with subclasses A through Z and my program crashes when I try to cast any element in the the vector to the subclass. I'm casting by doing the following:
A subclass = *((A * ) &vector[0]);
What am i doing wrong?
You should use dynamic_cast when casting pointers from one type to another in your use case.
The one you are using is a C style cast and I strongly suggest you to go with a dynamic_cast.
So your code should look something like:
if(dynamic_cast<A *>(vector[0]))
A subclass = *(dynamic_cast<A *>(vector[0]));
When a dynamic_cast fails it will return a NULL pointer and you should take care of it appropriately.
Refer dynamic_cast and static_cast in C++ for more information.
Additionally When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? will help you understand a lot more types of casts.
A meaningful usage would be
A &subclassref = vector[0]);
In above line, no new object is created.
BTW what is the type of your vector and what exactly do you want to achieve? If you store objects of type A to Z in a single vector, it may at some point of time suffer object slicing.
This answer may be wrong because I'm making a guess as to how you have filled the std::vector<>.
You simply cannot put objects of subclasses into an std::vector<Base>. All objects in an std::vector<Base> are precisely of type Base. If you try something like this:
std::vector<Base> myVec;
myVec.push_back(Derived1(...));
you first construct an object of class Derived1 which is subsequently spliced into an object of class Base, i. e. a new object of class Base is copy-constructed from the derived object. Only this copy constructed base class object ends up in the std::vector<>.
If you want to have an std::vector<> of polymorphic objects, you must use a pointer type as the template argument (and consequently allocate the contained objects with new).

unique_ptr and polymorphism

I have some code that currently uses raw pointers, and I want to change to smart pointers. This helps cleanup the code in various ways. Anyway, I have factory methods that return objects and its the caller's responsibility to manager them. Ownership isn't shared and so I figure unique_ptr would be suitable. The objects I return generally all derive from a single base class, Object.
For example,
class Object { ... };
class Number : public Object { ... };
class String : public Object { ... };
std::unique_ptr<Number> State::NewNumber(double value)
{
return std::unique_ptr<Number>(new Number(this, value));
}
std::unique_ptr<String> State::NewString(const char* value)
{
return std::unique_ptr<String>(new String(this, value));
}
The objects returned quite often need to be passed to another function, which operates on objects of type Object (the base class). Without any smart pointers the code is like this.
void Push(const Object* object) { ... } // push simply pushes the value contained by object onto a stack, which makes a copy of the value
Number* number = NewNumber(5);
Push(number);
When converting this code to use unique_ptrs I've run into issues with polymorphism. Initially I decided to simply change the definition of Push to use unique_ptrs too, but this generates compile errors when trying to use derived types. I could allocate objects as the base type, like
std::unique_ptr<Object> number = NewNumber(5);
and pass those to Push - which of course works. However I often need to call methods on the derived type. In the end I decided to make Push operate on a pointer to the object stored by the unique_ptr.
void Push(const Object* object) { ... }
std::unique_ptr<Object> number = NewNumber(5);
Push(number.get());
Now, to the reason for posting. I'm wanting to know if this is the normal way to solve the problem I had? Is it better to have Push operate on the unique_ptr vs the object itself? If so how does one solve the polymorphism issues? I would assume that simply casting the ptrs wouldn't work. Is it common to need to get the underlying pointer from a smart pointer?
Thanks, sorry if the question isn't clear (just let me know).
edit: I think my Push function was a bit ambiguous. It makes a copy of the underlying value and doesn't actually modify, nor store, the input object.
Initially I decided to simply change the definition of Push to use
unique_ptrs too, but this generates compile errors when trying to use
derived types.
You likely did not correctly deal with uniqueness.
void push(std::unique_ptr<int>);
int main() {
std::unique_ptr<int> i;
push(i); // Illegal: tries to copy i.
}
If this compiled, it would trivially break the invariant of unique_ptr, that only one unique_ptr owns an object, because both i and the local argument in push would own that int, so it is illegal. unique_ptr is move only, it's not copyable. It has nothing to do with derived to base conversion, which unique_ptr handles completely correctly.
If push owns the object, then use std::move to move it there. If it doesn't, then use a raw pointer or reference, because that's what you use for a non-owning alias.
Well, if your functions operate on the (pointed to) object itself and don't need its address, neither take any ownership, and, as I guess, always need a valid object (fail when passed a nullptr), why do they take pointers at all?
Do it properly and make them take references:
void Push(const Object& object) { ... }
Then the calling code looks exactly the same for raw and smart pointers:
auto number = NewNumber(5);
Push(*number);
EDIT: But of course no matter if using references or pointers, don't make Push take a std::unique_ptr if it doesn't take ownership of the passed object (which would make it steal the ownership from the passed pointer). Or in general don't use owning pointers when the pointed to object is not to be owned, std::shared_ptr isn't anything different in this regard and is as worse a choice as a std::unique_ptr for Push's parameter if there is no ownership to be taken by Push.
If Push does not take owenrship, it should probably take reference instead of pointer. And most probably a const one. So you'll have
Push(*number);
Now that's obviously only valid if Push isn't going to keep the pointer anywhere past it's return. If it does I suspect you should try to rethink the ownership first.
Here's a polymorphism example using unique pointer:
vector<unique_ptr<ICreature>> creatures;
creatures.emplace_back(new Human);
creatures.emplace_back(new Fish);
unique_ptr<vector<string>> pLog(new vector<string>());
for each (auto& creature in creatures)
{
auto state = creature->Move(*pLog);
}

Safe way of casting void* to something higher?

I've got a generic class that manages resources of all kinds of types, but since I don't want to create an instance of ResourceManager for every T there is (thus having one resource manager for each type T), I have to make the type of T unknown to the ResourceManager class.
I do this by saving a map of void* pointers and converting them back to the required format if someone requests a certain type out of a templated Load() method;
template <typename T>
T* Load(const std::string &location)
{
//do some stuff here
//everybody take cover!!!
return static_cast<T*>(m_resources[location]);
}
I use template specialization to introduce different Loaders to the class:
template<>
AwesomeType* Load(const std::string &location)
{
//etc.
return static_cast<AwesomeType*>(m_resources[location]);
}
I am aware that this is ugly, but there is no way around it right now. I could introduce static maps in the inside of the specialized Load methods, but that way I can't bind the lifetime of the resources to the lifetime of an ResourceManager object, which is an essential feature.
But since this is somewhat dangerous (since those void* pointers can be anything), I'd like to at least check at runtime if the conversion is going to work, so I can react to it without having the application crash.
How can I do this?
There is no way to check what you can cast void* to, unless you store additional information that indicates the actual type with each pointer.
A more "C++ way" to do what you want is to derive each resource class from an abstract base class Resource, and store a map of pointers to Resource in your resource manager. Then you can use dynamic_cast<T*> to convert to the required type, and this will return NULL if the pointer is to an object of the wrong type. Or (depending on what you want to do) you can simply return a Resource* pointer and use virtual functions to implement the functionality of each resource.
You can easily do this, if you extend your saved value type - make it a struct that also saves a type_info object:
#include <type_info>
struct ResourceInfo
{
std::type_info const& info;
void* ptr;
};
// ...
// just to give you the general idea
template<class Res>
void CacheResource(std::string const& location, Res* res)
{
ResourceInfo ri = { typeid(Res), res };
m_resources.insert(std::make_pair(location, ri));
}
template<class Res>
Res* Load(std::string const& location)
{
map_type::const_iterator res_it = m_resources.find(location);
if(res_it != m_resources.end())
{
if(typeid(Res) != res_it->second.info)
{
throw SorryBuddyWrongResourceType(some_info_here);
}
return static_cast<Res*>(res_it->second.ptr);
}
}
This is similar to how I do it, but I use a shared_ptr<void> to save the resources.
(I'm sure this is already answered by many other questions about void pointers, but here we go ...)
But since this is somewhat dangerous
(since those void* pointers can be
anything), I'd like to at least check
at runtime if the conversion is going
to work, so I can react to it without
having the application crash.
You cannot check. This is the thing about void* pointers. You don't have a clue what they are pointing to, and you cannot (are not allowed to) inspect the memory they point to without knowing its type.
If you have a void* you simply must know beforehand what it is really pointing to and then cast appropriately.

How to store different data types in one list? (C++)

I need to store a list of various properties of an object. Property consists of a name and data, which can be of any datatype.
I know I can make a class "Property", and extend it with different PropertySubClasses which only differ with the datatype they are storing, but it does not feel right.
class Property
{
Property(std::string name);
virtual ~Property();
std::string m_name;
};
class PropertyBoolean : Property
{
PropertyBoolean(std::string name, bool data);
bool m_data;
};
class PropertyFloat : Property
{
PropertyFloat(std::string name, float data);
float m_data;
};
class PropertyVector : Property
{
PropertyVector(std::string name, std::vector<float> data);
std::vector<float> m_data;
};
Now I can store all kinds of properties in a
std::vector<Property*>
and to get the data, I can cast the object to the subclass. Or I can make a pure virtual function to do something with the data inside the function without the need of casting.
Anyways, this does not feel right to create these different kind of subclasses which only differ by the data type they are storing. Is there any other convenient way to achieve similar behavior?
I do not have access to Boost.
C++ is a multi-paradigm language. It shines brightest and is most powerful where paradigms are mixed.
class Property
{
public:
Property(const std::string& name) //note: we don't lightly copy strings in C++
: m_name(name) {}
virtual ~Property() {}
private:
std::string m_name;
};
template< typename T >
class TypedProperty : public Property
{
public:
TypedProperty (const std::string& name, const T& data)
: Property(name), m_data(data);
private:
T m_data;
};
typedef std::vector< std::shared_ptr<Property> > property_list_type;
Edit: Why using std::shared_ptr<Property> instead of Property*?
Consider this code:
void f()
{
std::vector<Property*> my_property_list;
for(unsigned int u=0; u<10; ++u)
my_property_list.push_back(new Property(u));
use_property_list(my_property_list);
for(std::vector<Property*>::iterator it=my_property_list.begin();
it!=my_property_list.end(); ++it)
delete *it;
}
That for loop there attempts to cleanup, deleting all the properties in the vector, just before it goes out of scope and takes all the pointers with it.
Now, while this might seem fine for a novice, if you're an only mildly experienced C++ developer, that code should raise alarm bells as soon as you look at it.
The problem is that the call to use_property_list() might throw an exception. If so, the function f() will be left right away. In order to properly cleanup, the destructors for all automatic objects created in f() will be called. That is, my_property_list will be properly destroyed. std::vector's destructor will then nicely cleanup the data it holds. However, it holds pointers, and how should std::vector know whether these pointers are the last ones referencing their objects?
Since it doesn't know, it won't delete the objects, it will only destroy the pointers when it destroys its content, leaving you with objects on the heap that you don't have any pointers to anymore. This is what's called a "leak".
In order to avoid that, you would need to catch all exceptions, clean up the properties, and the rethrow the exception. But then, ten years from now, someone has to add a new feature to the 10MLoC application this has grown to, and, being in a hurry, adds code which leaves that function prematurely when some condition holds. The code is tested and it works and doesn't crash - only the server it's part of now leaks a few bytes an hour, making it crash due to being out of memory about once a week. Finding that makes for many hours of fine debugging.
Bottom line: Never manage resources manually, always wrap them in objects of a class designed to handle exactly one instance of such a resource. For dynamically allocated objects, those handles are called "smart pointer", and the most used one is shared_ptr.
A lower-level way is to use a union
class Property
union {
int int_data;
bool bool_data;
std::cstring* string_data;
};
enum { INT_PROP, BOOL_PROP, STRING_PROP } data_type;
// ... more smarts ...
};
Dunno why your other solution doesn't feel right, so I don't know if this way would feel better to you.
EDIT: Some more code to give an example of usage.
Property car = collection_of_properties.head();
if (car.data_type == Property::INT_PROP) {
printf("The integer property is %d\n", car.int_data);
} // etc.
I'd probably put that sort of logic into a method of the class where possible. You'd also have members such as this constructor to keep the data and type field in sync:
Property::Property(bool value) {
bool_data = value;
data_type = BOOL_PROP;
}
I suggest boost::variant or boost::any. [Related question]
Write a template class Property<T> that derives from Property with a data member of type T
Another possible solution is to write a intermediate class managing the pointers to Property classes:
class Bla {
private:
Property* mp
public:
explicit Bla(Property* p) : mp(p) { }
~Bla() { delete p; }
// The standard copy constructor
// and assignment operator
// aren't sufficient in this case:
// They would only copy the
// pointer mp (shallow copy)
Bla(const Bla* b) : mp(b.mp->clone()) { }
Bla& operator = (Bla b) { // copy'n'swap trick
swap(b);
return *this;
}
void swap(Bla& b) {
using std::swap; // #include <algorithm>
swap(mp, b.mp);
}
Property* operator -> () const {
return mp;
}
Property& operator * () const {
return *mp;
}
};
You have to add a virtual clone method to your classes returning a pointer to a newly created copy of itself:
class StringProperty : public Property {
// ...
public:
// ...
virtual Property* clone() { return new StringProperty(*this); }
// ...
};
Then you'll be able to do this:
std::vector<Bla> v;
v.push_back(Bla(new StringProperty("Name", "Jon Doe")));
// ...
std::vector<Bla>::const_iterator i = v.begin();
(*i)->some_virtual_method();
Leaving the scope of v means that all Blas will be destroyed freeing automatically the pointers they're holding. Due to its overloaded dereferencing and indirection operator the class Bla behaves like an ordinary pointer. In the last line *i returns a reference to a Bla object and using -> means the same as if it was a pointer to a Property object.
A possible drawback of this approach is that you always get a heap operation (a new and a delete) if the intermediate objects must be copied around. This happens for example if you exceed the vector's capacity and all intermediate objects must be copied to a new piece of memory.
In the new standard (i.e. c++0x) you'll be able to use the unique_ptr template: It
can be used inside the standard containers (in contrast to the auto_ptr which must not be used in the standard containers),
offers the usually faster move semantics (it can easily passed around) and
takes care over the held pointers (it frees them automatically).
I see that there are lots of shots at trying to solve your problem by now, but I have a feeling that you're looking in the wrong end - why do you actually want to do this in the first place? Is there some interesting functionality in the base class that you have omitted to specify?
The fact that you'd be forced to switch on a property type id to do what you want with a specific instance is a code smell, especially when the subclasses have absolutely nothing in common via the base class other than a name (which is the type id in this case).
Starting with C++ 17 we have something called as std::variant and std::any.
std::variant
An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value.
std::any
The class any describes a type-safe container for single values of any copy constructible type.
An object of class any stores an instance of any type that satisfies the constructor requirements or is empty, and this is referred to as the state of the class any object. The stored instance is called the contained object. Two states are equivalent if they are either both empty or if both are not empty and if the contained objects are equivalent.
The non-member any_cast functions provide type-safe access to the contained object.
You can probably do this with the Boost library, or you could create a class with a type code and a void pointer to the data, but it would mean giving up some of the type safety of C++. In other words, if you have a property "foo", whose value is an integer, and give it a string value instead, the compiler will not find the error for you.
I would recommend revisiting your design, and re-evaluating whether or not you really need so much flexibility. Do you really need to be able to handle properties of any type? If you can narrow it down to just a few types, you may be able to come up with a solution using inheritance or templates, without having to "fight the language".

Ensuring pointer is not deleted

I've stumbled onto something I can't figure out, so I think I'm missing something in the greater C++ picture.
In short, my question is: how to keep a mutable, non-deletable, possibly NULL instance of an object in a class.
The longer version is:
I have the following scenario: a bunch of classes (which I can change slightly, but not thoroughly refactor), most of which need to use an object. This object, while mutable, is managed by someone else so it must not be deleted.
Some of the classes in the bunch do not need such an object - they reuse code from other classes, but through the available parameters supplied to these classes it is guaranteed that even if an object is supplied, it will not be used.
The current implementation uses a pointer-to-const-object (const Obj *). This, in turn, means all the object's methods must be const and most fields mutable. This is a messy solution since the fields declared mutable are available for inspection (so quite the opposite of the c++ lite entry here). It also only partially solves the "do-not-delete-this-here" issue (compiler does not complain but a const in front of the object is an indication).
If I used a reference to this object, I'd force some callers to create a "dummy" object and provide it to the class they are instantiating. This is also messy, besides being a waste of resources. I cannot create a global object to can stand in for a "NULL" reference due to project restrictions.
I feel that the reference is the tool I need, but I cannot refactor the classes involved to such an extent as to have the object disappear from their implementations where it is not used (it can be done, but it is not simple and it would not be fast). So I want to implement something simpler, which will just draw an alarm signal if anyone tries to misuse this object, but keeps my object mutable.
The best solution I can think of is using a const-pointer-to-object (Obj * const) - this does not make the compiler complain, but I have my mutable object and a sort-of alarm signal -through the const - in place as well.
Does anyone have a better idea ?
I've traditionally seen these kind of scenarios implemented using a shared_ptr/weak_ptr combo. See here.
The owner/deleter would get a
boost::shared_ptr<T>
Your class would get a
boost::weak_ptr<T>
To reassign the weak ptr, simply reassign the pointer:
void MyClass::Reassign(boost::weak_ptr<T> tPtr)
{
m_tPtr = tPtr;
}
To use the weak ptr, first check to see if it's still around:
void MyClass::Use()
{
boost::shared_ptr<T> m_temporarySharedPtr = m_tPtr.lock();
if (m_temporarySharedPtr)
{
//...
}
}
The weak ptr can be made "NULL" by reseting it, or assigning it to an empty shared_ptr
void MyClass::MakeNull()
{
m_tPtr.reset();
}
You can make the destructor of that object private. That will trigger compile time error on attemp to delete object. Also you should allow restcted code to delete object by using friends mechanism or member function.
You can put a wrapper around the pointer to allow modification but not deletion:
template <typename T> class Wrapper
{
public:
Wrapper(T *p=0) : pointer(p) {}
T *operator->() {return pointer;}
T const *operator->() const {return pointer;}
operator bool() const {return pointer;}
private:
T *pointer;
};
You can use this just like a pointer to the template type in some contexts, but can't call delete on it. The wrapped type must be a struct or class type (i.e. a type where -> makes sense). Then one of your classes that uses, but doesn't manage the lifetime of, the object would look a bit like this:
class User
{
public:
void Assign(Object *o) {object = o;}
void UseObject() {if (object) object->Use();}
private:
Wrapper<Object> object;
};
Technically, you can still get at the raw pointer, but the code to do it is very wrong-looking:
delete wrapper.operator->();
Sounds like a case for a shared_ptr.
An alternative (if allowed by your restircitons) would be to create a dummy object similar to a shared pointer to act as a wrapper between the object in question and your classes.
Your classes can attempt to delete this object if they wish, but it itself will leave the original object untouched. Overload the * operator and you can use it transparently.
something like this?...
the Obj class is an aggregation of your new class, you point at it with an Obj* cont pObj, which you set up at the creation of your new class (or leave as 0 if it's not used), you then check pObj before calling any of its functions?
if ( pObj ){ pObj->foo(); }
if the function foo's incorrectly defined as mutable then you need to fix its declaration.
your new class isn't responsible for cleaning up/deleting the Obj class.