The dynamic_cast operator is returning zero (0) when I apply to a pointer that points to an instance of a multiply inherited object. I don't understand why.
The hierarchy:
class Field_Interface
{
public:
virtual const std::string get_field_name(void) const = 0; // Just to make the class abstract.
};
class Record_ID_Interface
{
public:
virtual bool has_valid_id(void) const = 0;
};
class Record_ID_As_Field
: public Field_Interface,
public Record_ID_Interface
{
// This class behaves as a Field and a Record_ID.
// ...
}
// A demonstration function
void Print_Field_Name(const Field_Interface * p_field)
{
if (p_field)
{
cout << p_field->get_field_name() << endl;
}
return;
}
// A main function for demonstration
int main(void)
{
Record_ID_As_Field * p_record_id = 0;
p_record_id = new Record_ID_As_Field;
if (p_record_id)
{
// (1) This is the trouble line
Print_Field_Name(dynamic_cast<Field_Interface *>(p_record_id));
}
return 0;
}
I want to have the Record_ID_As_Field to be treated as a Field_Interface, but also fit in where Record_ID_Interface are required.
Why is dynamic_cast in (1) above returning 0, and how do I resolve this?
I am using Visual Studion 2008 on Windows XP.
Note: For simplicity, I am using fundamental pointers in this example. Actual code uses boost::shared_ptr.
Note: For simplicity, I am using fundamental pointers in this example. Actual code uses boost::shared_ptr.
And that's your problem right there: You cannot dynamic_cast a shared_ptr<A> to a shared_ptr<B> since those two types are not actually related to each other, even if A and B are.
Luckily in the specific case in your question the dynamic_cast shouldn't be necessary, since Record_ID_As_Field* should be implicitly convertible to a Field_Interface* (since the one is derived from the other). shared_ptr implements conversion operators that lift these implicit conversions to the respective shared_ptr objects, so shared_ptr<Record_ID_As_Field> should be implicitly convertible to shared_ptr<Field_Interface>.
If you leave out the dynamic_cast, it should work.
If you'd actually need to do a dynamic cast, you could use a special constructor provided by shared_ptr:
shared_ptr<Record_ID_As_Field> raf;
shared_ptr<Field_Interface> fi(raf, dynamic_cast<FieldInterface*>(raf.get());
(I'm not sure what would happen there if the dynamic_cast fails, so you should investigate what's the best way to handle that situation.)
Related
I created a vector that stores any type of value (int, bool, string, &, object,...). I can store stuff, but i have no idea how to get an specific element ([index]). EDIT: (without adding the type)
I haven't tried many things because i have no clue. The only tecnic i can think of is dynamic_cast, but since is a template makes no sense.
#include <vector>
#include <iostream>
struct slot {
virtual void print() = 0;
};
template<typename kind>
struct item : public slot {
kind value;
item(kind value) : value{ value } {};
void print()override { std::cout << value<<std::endl; }
};
class Bag {
std::vector<slot*> backpack;
public:
template<typename kind>
void append(kind stuff) {
backpack.push_back(new item<kind>(stuff));
}
void print_to_test() {
for (slot* it : backpack) { it->print(); }
}
//kind get()...How do i get an item value?
};
Bag bag;
bag.append(1);
bag.append(true);
bag.append("Hola");
bag.append(1232131);
void* a = nullptr;
bag.append(a);
bag.print_to_test();
//works fine, prints everything
//but can't get an specific value, like bag[index]
The dynamic cast will work. Note that it requires at least one virtual method - a destructor can be used if nothing else.
Yes, there isn't a way how can you reliably retrieve the value. C++ doesn't have a general object base as other languages nor any useful runtime reflection.
What you've implemented is known as type erasure and is actually used in e.g. std::function or std::any.
You should not use raw pointers and new for ownership. Use std::unique_ptr instead. Also since you only refer to the objects through the base class you need the virtual destructor. Otherwise, you won't be able to delete them correctly, again one more reason for std::unique_ptr as it deletes the pointer by itself.
If you want to get the value, what would you do with it? To quote Bjarne Stroustrup:
There is no useful universal class: a truly universal carries no semantics of its own.
Yes, you can store this value in std::any, but that's it, what would you want to do with it? Print it? Well, in that case it's no longer any but printable as in your example, so either use templates or virtual methods to express these traits in the types of the stored objects.
Consider using std::variant for known set of possible types and prefer std::any to owning void*. If you need the latter rethink your design choices first.
As others pointed out, dynamic_cast will work fine (as long as the caller knows what type is in the specific index) :
item<int>& someInt = dynamic_cast<item<int>&>(*bag.backpack[0]);
std::cout << "someInt: ";
someInt.print();
Note: You didn't provide accessor to backpack member, so I assumed it's public
Output:
someInt: 1
I'm trying to write a Unity-style get component method. This is my code so far. It compiles but will return the first component it finds rather than the correct one. I think I'm using static_cast wrong. What is a better way to do this? Note I don't want to hard code component types, I want to be able to compile this engine and use anything that inherits from Component to be able to use this system. Also note that each component needs to return as itself, not a component *, as this would hide child functionality.
compStruct.components is a vector of component *s.
template <typename CompType>
inline CompType getComponent()
{
for(Component * currComp : compStruct.components)
{
if (static_cast<CompType>(currComp)!= nullptr)
{
return static_cast<CompType>(currComp);
}
}
return nullptr;
}
Here is an example of a generic component
#pragma once
#include "Component.h"
#include "Animation2D.h"
class AnimationComponent : public Component
{
public:
AnimationComponent(GameObject*x) :Component(x) {}
~AnimationComponent() {}
void stepAnimation(double delta);
//add overload for 3d animations
int addAnimation(Animation2D);
void setAnimation(int);
private:
};
And the component base class:
#pragma once
class GameObject;
class Component
{
public:
Component(GameObject * h) { host = h; }
virtual ~Component() {}
GameObject* getHost() { return host; }
protected:
GameObject * host = nullptr;
};
There's some fundamental misunderstanding about static_cast: it will just do the cast, and it is your responsibility to assure the pointer casted actually points to an object of the target type. static_cast will only return a null pointer if the source pointer already was itself, but never on type mismatch!
class B { /*...*/ };
class D1 : public B { };
class D2 : public B { };
D1 d1;
B* b = &d1;
D2* d2 = static_cast<D2*>(b);
d2 will be a pointer to d1 (in some cases involving multiple inheritance there can be an offset), but interpret the latter's data totally differently (unless D1 and D2 are layout compatible) and you might end up in hell!
Now first off, I personally prefer a modified signature:
template <typename CompType>
inline CompType* getComponent();
// ^
It allows calling your function like getComponent<SomeType>() instead of getComponent<SomeType*>(), additionally it allows using pointers inside the function body, which is way clearer, see my my appropriately adjusted code below.
Then what you actually need is a dynamic_cast (adjusting your code a little to my personal preferences...):
CompType* result = nullptr; // pointer: see above!
for(Component * currComp : compStruct.components)
{
result = dynamic_cast<CompType*>(currComp);
if(result)
break;
}
return result;
Edit: Catching up Nshant Singh's comment:
dynamic_cast actually is quite expensive.
An alternative could be an unordered_map, replacing your vector (example how to set up can be found at type_index documentation; of course, you'd place your objects instead of strings...). Then your lookup might look like:
auto i = map.find(std::type_index(typeid(CompType));
return i == map.end() ? nullptr : static_cast<CompType*>(i->second);
// now, you CAN use static cast, as the map lookup provided you the
// necessary guarantee that the type of the pointee is correct!
static_cast is definitely not what you want: it's static (compile time), so it cannot determine any runtime information.
What you want is dynamic_cast instead. Note that this has several requirements, all of which are fulfilled by your code:
The classes must be polymorphic. That's covered, because Component has a virtual destructor.
The classes must be defined (not just declared) at the point of the cast. That's covered as well, because getComponent is a template and the type in the cast depends on its template parameters (it is one, in fact). Therefore, the definition only needs to be visible where the template is instantiated (i.e. where getComponent is called). Since you're presumably doing the casting to access the concrete component's members, you must have its definition visible, so all is well.
I'm currently investigating the interplay between polymorphic types and assignment operations. My main concern is whether or not someone might try assigning the value of a base class to an object of a derived class, which would cause problems.
From this answer I learned that the assignment operator of the base class is always hidden by the implicitely defined assignment operator of the derived class. So for assignment to a simple variable, incorrect types will cause compiler errors. However, this is not true if the assignment occurs via a reference:
class A { public: int a; };
class B : public A { public: int b; };
int main() {
A a; a.a = 1;
B b; b.a = 2; b.b = 3;
// b = a; // good: won't compile
A& c = b;
c = a; // bad: inconcistent assignment
return b.a*10 + b.b; // returns 13
}
This form of assignment would likely lead to inconcistent object state, however there is no compiler warning and the code looks non-evil to me at first glance.
Is there any established idiom to detect such issues?
I guess I only can hope for run-time detection, throwing an exception if I find such an invalid assignment. The best approach I can think of just now is a user-defined assigment operator in the base class, which uses run-time type information to ensure that this is actually a pointer to an instance of base, not to a derived class, and then does a manual member-by-member copy. This sounds like a lot of overhead, and severely impact code readability. Is there something easier?
Edit: Since the applicability of some approaches seems to depend on what I want to do, here are some details.
I have two mathematical concepts, say ring and field. Every field is a ring, but not conversely. There are several implementations for each, and they share common base classes, namely AbstractRing and AbstractField, the latter derived from the former. Now I try to implement easy-to-write by-reference semantics based on std::shared_ptr. So my Ring class contains a std::shared_ptr<AbstractRing> holding its implementation, and a bunch of methods forwarding to that. I'd like to write Field as inheriting from Ring so I don't have to repeat those methods. The methods specific to a field would simply cast the pointer to AbstractField, and I'd like to do that cast statically. I can ensure that the pointer is actually an AbstractField at construction, but I'm worried that someone will assign a Ring to a Ring& which is actually a Field, thus breaking my assumed invariant about the contained shared pointer.
Since the assignment to a downcast type reference can't be detected at compile time I would suggest a dynamic solution. It's an unusual case and I'd usually be against this, but using a virtual assignment operator might be required.
class Ring {
virtual Ring& operator = ( const Ring& ring ) {
/* Do ring assignment stuff. */
return *this;
}
};
class Field {
virtual Ring& operator = ( const Ring& ring ) {
/* Trying to assign a Ring to a Field. */
throw someTypeError();
}
virtual Field& operator = ( const Field& field ) {
/* Allow assignment of complete fields. */
return *this;
}
};
This is probably the most sensible approach.
An alternative may be to create a template class for references that can keep track of this and simply forbid the usage of basic pointers * and references &. A templated solution may be trickier to implement correctly but would allow static typechecking that forbids the downcast. Here's a basic version that at least for me correctly gives a compilation error with "noDerivs( b )" being the origin of the error, using GCC 4.8 and the -std=c++11 flag (for static_assert).
#include <type_traits>
template<class T>
struct CompleteRef {
T& ref;
template<class S>
CompleteRef( S& ref ) : ref( ref ) {
static_assert( std::is_same<T,S>::value, "Downcasting not allowed" );
}
T& get() const { return ref; }
};
class A { int a; };
class B : public A { int b; };
void noDerivs( CompleteRef<A> a_ref ) {
A& a = a_ref.get();
}
int main() {
A a;
B b;
noDerivs( a );
noDerivs( b );
return 0;
}
This specific template can still be fooled if the user first creates a reference of his own and passes that as an argument. In the end, guarding your users from doing stupid things is an hopeless endeavor. Sometimes all you can do is give a fair warning and present a detailed best-practice documentation.
I have done a little research on dynamic_casting, and I read that it creates something called the RTTI,
which is loaded in RAM too at start-up. At some platforms this isn't supported too I think. So I was wondering if there was any good solution to avoid it.
Let's say I have Statement class
class Statement
{
std::list<Operand*> operands;
};
and a Operand is a class with more subclasses like, memory address, register, ect. ( For some wondering, I am trying to make an assembler.:P
I can't go downcasting with dynamic_cast, which is also bad if I could. But what if I added a enumeration to Operand, which defines it's Type, so I can downcast with static_cast by using it's type.
I could make it a const, and define it in the constructor of every subclass right?
I am looking forward to what you all think.
Christian
Making a type - is an option.
But consider making a generic interface for Operand. So your memory address, register, ect will inplement that interface and you will be able to treat them polymorphic.
In case you can't invent such interface - consider redesigning your classes because it looks like they don't need to have a common interface.
If you need code reuse - go with composition, not inheritance
If you decide you want to down cast, you may consider using an interface to get to the appropriate type. But, you could also list out the subclasses explicitly as well.
class Operand {
public:
enum Type { OT_Address, OT_Register, /*...*/ };
virtual Type type () const = 0;
virtual AddressOperand * isAddress () { return 0; }
virtual RegisterOperand * isRegister () { return 0; }
//...
};
Then, instead of a down cast, you would simply invoke the method associated with the type. The derived class would implement it:
class AddressOperand : public Operand {
public:
Operand::Type type () const { return Operand::OT_Address; }
AddressOperand * isAddress () { return this; }
//...
};
What, if any, c++ constructs are there for listing the ancestors of a class at runtime?
Basically, I have a class which stores a pointer to any object, including possibly a primitive type (somewhat like boost::any, which I don't want to use because I need to retain ownership of my objects). Internally, this pointer is a void*, but the goal of this class is to wrap the void* with runtime type-safety. The assignment operator is templated, so at assignment time I take the typeid() of the incoming pointer and store it. Then when I cast back later, I can check the typeid() of the cast type against the stored type_info. If it mismatches, the cast will throw an exception.
But there's a problem: It seems I lose polymorphism. Let's say B is a base of D. If I store a pointer to D in my class, then the stored type_info will also be of D. Then later on, I might want to retrieve a B pointer. If I use my class's method to cast to B*, then typeid(B) == typeid(D) fails, and the cast raises an exception, even though D->B conversion is safe. Dynamic_cast<>() doesn't apply here, since I'm operating on a void* and not an ancestor of B or D.
What I would like to be able to do is check is_ancestor(typeid(B), typeid(D)). Is this possible? (And isn't this what dynamic_cast<> is doing behind the scenes?)
If not, then I am thinking of taking a second approach anyway: implement a a class TypeInfo, whose derived classes are templated singletons. I can then store whatever information I like in these classes, and then keep pointers to them in my AnyPointer class. This would allow me to generate/store the ancestor information at compile time in a more accessible way. So failing option #1 (a built-in way of listing ancestors given only information available at runtime), is there a construct/procedure I can use which will allow the ancestor information to be generated and stored automatically at compile-time, preferably without having to explicitly input that "class A derives from B and C; C derives from D" etc.? Once I have this, is there a safe way to actually perform that cast?
I had a similar problem which I solved through exceptions! I wrote an article about that:
Part 1, Part 2 and code
Ok. Following Peter's advise the outline of the idea follows. It relies on the fact that if D derives from B and a pointer to D is thrown, then a catch clause expecting a pointer to B will be activated.
One can then write a class (in my article I've called it any_ptr) whose template constructor accepts a T* and stores a copy of it as a void*. The class implements a mechanism that statically cast the void* to its original type T* and throws the result. A catch clause expecting U* where U = T or U is a base of T will be activated and this strategy is the key to implementing a test as in the original question.
EDIT: (by Matthieu M. for answers are best self-contained, please refer to Dr Dobbs for the full answer)
class any_ptr {
void* ptr_;
void (*thr_)(void*);
template <typename T>
static void thrower(void* ptr) { throw static_cast<T*>(ptr); }
public:
template <typename T>
any_ptr(T* ptr) : ptr_(ptr), thr_(&thrower<T>) {}
template <typename U>
U* cast() const {
try { thr_(ptr_); }
catch (U* ptr) { return ptr; }
catch (...) {}
return 0;
}
};
The information is (often) there within the implementation. There's no standard C++ way to access it though, it's not exposed. If you're willing to tie yourself to specific implementations or sets of implementations you can play a dirty game to find the information still.
An example for gcc, using the Itanium ABI is:
#include <cassert>
#include <typeinfo>
#include <cxxabi.h>
#include <iostream>
bool is_ancestor(const std::type_info& a, const std::type_info& b);
namespace {
bool walk_tree(const __cxxabiv1::__si_class_type_info *si, const std::type_info& a) {
return si->__base_type == &a ? true : is_ancestor(a, *si->__base_type);
}
bool walk_tree(const __cxxabiv1::__vmi_class_type_info *mi, const std::type_info& a) {
for (unsigned int i = 0; i < mi->__base_count; ++i) {
if (is_ancestor(a, *mi->__base_info[i].__base_type))
return true;
}
return false;
}
}
bool is_ancestor(const std::type_info& a, const std::type_info& b) {
if (a==b)
return true;
const __cxxabiv1::__si_class_type_info *si = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&b);
if (si)
return walk_tree(si, a);
const __cxxabiv1::__vmi_class_type_info *mi = dynamic_cast<const __cxxabiv1::__vmi_class_type_info*>(&b);
if (mi)
return walk_tree(mi, a);
return false;
}
struct foo {};
struct bar : foo {};
struct baz {};
struct crazy : virtual foo, virtual bar, virtual baz {};
int main() {
std::cout << is_ancestor(typeid(foo), typeid(bar)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(baz)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(int)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(crazy)) << "\n";
}
Where I cast the type_info to the real type that's used internally and then recursively used that to walk the inheritance tree.
I wouldn't recommend doing this in real code, but as an exercise in implementation details it's not impossible.
First, what you are asking for cannot be implemented just on top of type_info.
In C++, for a cast to occur from one object to another, you need more than blindly assuming a type can be used as another, you also need to adjust the pointer, because of multi-inheritance (compile-time offset) and virtual inheritance (runtime offset).
The only way to safely cast a value from a type into another, is to use static_cast (works for single or multi-inheritance) and dynamic_cast (also works for virtual inheritance and actually checks the runtime values).
Unfortunately, this is actually incompatible with type erasure (the old template-virtual incompatibility).
If you limit yourself to non-virtual inheritance, I think it should be possible to achieve this by storing the offsets of conversions to various bases in some Configuration data (the singletons you are talking about).
For virtual inheritance, I can only think of a map of pairs of type_info to a void* (*caster)(void*).
And all this requires enumerating the possible casts manually :(
It is not possible using std::type_info since it does not provide a way to query inheritance information or to convert a std::type_info object to its corresponding type so that you could do the cast.
If you do have a list of all possible types you need to store in your any objects use boost::variant and its visitor.
While I can't think of any way to implement option #1, option #2 should be feasible if you can generate a compile-time list of the classes you would like to use. Filter this type list with boost::MPL and the is_base_of metafunction to get a list of valid-cast typeids, which can be compared to the saved typeid.