Here's my attempt to represent a simple problem I have:
Renderable* test1 = *(Renderable**) pointerToObject;
StaticObject* test2 = *(StaticObject**) pointerToObject;
test1->setTransparency(0.5f); // Crash here.
test2->setTransparency(0.75f); // Works here.
pointerToObject type is void* but inside it actually points to pointer to object (like Renderable**).
Renderable is an abstract class and StaticObject is a child class that implements Renderable.
When compiled, program crashes on test1->set() method, but works with test2->set().
Is it possible to get valid test1 object from pointerToObject without knowing about StaticObject?
EDIT
This is how I store this pointer:
StaticObject** udata = (StaticObject**) lua_newuserdata(state, sizeof(StaticObject*));
*udata = object;
object is pointer to StaticObject. I just noticed sizeof(StaticObject*) which is probably the cause of my problems. Documentation for methdod is here: lua_newuserdata. Is there still any way to achieve what I want without modifying lua_newuserdata method?
What is the type of the renderable object? In general, if you convert a pointer into a void* (there is no cast needed to do this) you must convert it back to its original type (which requires a cast) to use it. So if the type of renderable is StaticObject, the use of test1 is not valid.
StaticObject renderable;
void *pointerToObject = &renderable;
Renderable* test1 = (Renderable*)pointerToObject; // invalid pointer
StaticObject *test2 = (StaticObject*)pointerToObject; // okay
Related
So I was doing something like this:
Base * pParentPtr
// ... pParentPtr is used
// Cast result pointer
Derived* castedResult = (Derived*)pParentPtr;
// Copy the referenced object to stack object
Derived resultExplicitCopy = Derived(*castedResult);
// run Derived class functions
resultExplicitCopy.DeviredSpecialFunction();
// Free memory allocated by factory
delete pParentPtr;
Which means that the code uses pParentPtr but at the end we need it to be converted to Derived, then call a function that belongs only to Derived and then delete the initial pointer.
Although this works, the idea is to simplify the code. I thought on creating a contructor for Derived that takes a Base* for input:
Derived::Derived(Base* basePtr)
{
// Cast result pointer
Derived* castedResult = (Derived*)basePtr;
// Copy the referenced object to stack object
Derived resultExplicitCopy = Derived(*castedResult); // This looks bad
// run Derived class functions
resultExplicitCopy.DeviredSpecialFunction();
*this = resultExplicitCopy; // ??? this seems weird and dangerous
}
Creating a Derived instance inside the constructor seems like a bad idea, also reseting the whole object before it actually exists.
So, is there a way of pasing Base's pointer to Derived's constructor and properly building it?
I'd like it to look like this:
Base * pParentPtr
// ... pParentPtr is used
// Init derived with base
derivedInstance = Derived(pParentPtr);
// Free memory allocated by factory
delete pParentPtr;
The best way to deal with this would be to take a Base* in the constructor function and then manually setting the data fields in the constructor so for example. This is because when you call a constructor it will 'return' an instantiated version of that object to your specifications:
field1=basePtr->field1
I would avoid using the cast because it is a dangerous C cast as what it is doing is saying instead of treating what this pointer points to as having a Base type treat the memory as if it had a Derived type and if the memory doesn't match up there could be problems
This code is valid only if pParentPtr points to an object of class Derived. If it's true, then you can do one of these depending on the actual use case:
Directly call castedResult->DeviredSpecialFunction().
If you don't like the -> syntax for some reason (i'm assuming you're doing hobby project or it is not a peer-reviwed code, otherwise -> is perfectly fine), then you can "transform" pointer to a reference: Derived& resultExplicitCopy = (Derived&)(*castedResult) (note the two added ampersands).
Also I agree with comments noting that you should revise your design such that:
you don't blindly assume that pParentPtr points to Derived. Maybe the code above does the check already, but then still the following point holds:
you certainly shouldn't allow the construction of Derived form pointer Base if such construction blindly assumed that a pointer points to a Derived. Usually a class may be used in a different places in program, so a class's constructor should be clear in a way that you know what objects it may accept by looking at its signature. Having a proper parameter type makes it formally correct, and formal correctness actually makes things clearer. If constructor assumes its paremeter points to Derived, it should accept a Derived*, and accepting 'Base* would be incorrect as it allows a pointer to a non-Derived` object to be passed into it by mistake. In such a case the compiler can't help you by type checking.
Could you please clear up a question for me regarding pointer vs object in C++. I have the below code that has a class called "person" and a list that allows for 100 objects of that class type.
class person {...}
int main {
person* mylist;
mylist = new person[100];
mylist[0].set_name("John")
// ...
}
In this code I can call a method of the class by mylist[0].set_name() meaning (by my understanding) that mylist[0] is an object (hence the . operator to call a method). The code works fine.
I have another project where the "person" class is used as a base class to derive classes "carpenter" and "welder". The derived classes simply overwrite a virtual function called salary in the base "person" class to allow for a different calculation of salary.
person* mylist[100];
mylist[0] = new carpenter;
mylist[0]->set_name("John");
This code works fine as well. My question is - why in the first code I can call the set_name method using the . (meaning mylist[0] is an object) and in the second code I have to use the -> operator (meaning mylist[0] is a pointer to the object)?
T* represents a pointer type, which represents a variable that contains a "reference" (usually a memory address) to some instance of type T. Using a real world comparison, a T* pointer stands to T like a street address stands to a building.
Pointers allow you to refer to some instance owned by some other variable, and you can use a valid, non null instance of T* to read and write on a T. In this, they are similar to another C++ concept, references (written as T&), which allow you to alias variables, but differ significantly from pointers by not being objects in their own regard.
A pointer is, in fact, an object itself, with each pointer variable having its own unique address and being thus storable and referenceable. For instance, you can have pointers to pointers (T**) and references to pointers (T*&), but not pointers to references - pointers exist, while references may not (they are usually implemented as pointers underneath though).
To reflect the this "indirect" nature of pointers, C and C++ provide you with two different operators which allow you to dereference a pointer (* and ->), and to reference a variable (&).
For instance, you may do the following:
struct A { int x; };
// ...
A a {};
A *aptr { &a }; // `&` takes the address of `a` and stores it into the `aptr` variable of type `A*`
aptr->x = 33; // `->` is equivalent here to `(*aptr).x`, a.x is now 33
A a2 {};
A **aptrptr { &aptr }; // pointer to pointer
*aptrptr = &a2; // `aptr` now points to `a2`
operator-> is basically syntactic sugar that avoids you some cumbersome expressions like (*aptr).x.
References, being basically just aliases to something else, do not need any special syntax at all, and are always converted transparently when neeeded:
int x { 33 };
int &xref { x }; // `xref` refers to `x`
xref = 12; // `x` is now 33
int y = xref; // copies `x` into `y`, no special syntax needed
Pointers are also used in the C language to access arrays, which always decay to a pointer as soon as they are referred to in expressions. This is messy and it's one of the reasons std::vector and std::array should always be used in their place when feasible.
int x[33];
x[3] = 44; // equivalent to `*(&x[0] + 3) = 44`
Finally, the "indirect" nature of pointers and references allow C++ to convert a Derived* to a Base*, given that a derived class contains a full instance of its base (it gets more complicated with multiple inheritance though).
Every class that inherits or contains from another class containing virtual methods will include a hidden pointer to a _Virtual Method Table`, a list of pointers to functions which will be used to dispatch the virtual methods to the correct implementation.
PS: in modern C++, you should rarely need raw pointers. The correct approach is to use containers such as std::vector, std::array and std::string, and special pointer-like wrappers called smart pointers (like std::unique_ptr) every time you need a pointer for some reason. These will handle the lifetime of a pointer for you, avoiding memory leaks and vastly simplifying memory handling. For the same reason, the new operator should be mostly considered as being deprecated and should not be used at all (unless in placement new expressions, are potentially dangerous if used improperly).
basically the first case works like this: you have an array of objects. To access the object fields and methods you use . operator.
In the second case you have an array of pointers to an object. Pointer is just a memory address, that points to an object of some type. In your case, this is an array of pointers to class person. By default, these pointers are invalid; you have to set them to the address of some existing object. new creates an object on the heap, and returns you an address of that object. In order to access the value behind the pointer, you have to de-reference it. The syntax is this:
some_type obj;
some_type* ptr = &obj; // get the address of the object
(*ptr).some_method(); // de-reference the pointer and call it
ptr->some_method(); // same
I'm creating this question because I can't find any related solutions in dynamic_cast of object array on web, or just because I did not understand the concept of it, please lead me, Thank you
I'm currently working on a assignment which I have to use dynamic_cast to cast base class object (pointer) into it's subclasses object, to have access to others method in subclasses.
First of all I'll have this array
Hardware *object = new Hardware[100];
When it comes to need for access to subclasses of Hardware , I think I should do something like this:
Desktop *temp = dynamic_cast<Desktop*>(&object[0]);
But the temp resulting in NULL pointer
I asked some friend and they said I'll have to do something like
object[0] = new Desktop(//arguments);
Then only I can proceed to dynamic_cast of object[0], but it shows error(red lines) on the = operator :
no operator "=" matches these operands operand types are: Hardware = Desktop *
At the end I've tried many that similar to object[0] = new Desktop(//arguments); But didn't worked out, is there any steps that I've missed?
class Hardware //This is the base class
{
private:
string code;
double price;
public:
Hardware();
Hardware(string a, double b){
code = a;
price = b;
}
virtual void foo(){}
}
class Laptop: public Hardware //More of subclasses like this
{
private:
string brand;
public:
Laptop();
Laptop(string a, string b, double c):Hardware(b, c) {
brand = a;
}
}
int main(){
//Have to create one base class object with ptr array
Hardware *object = new Hardware[100];
//friend suggest: object[0] = new Desktop("Acer", "COMP-001", 1200.00);
//I wanted to use dynamic_cast like this
Desktop *temp = dynamic_cast<Desktop*>(&object[0]);
//To access to subclasses method and constructor
temp->displayLaptop();
}
Expecting results that I can downcast the Hardware class into Subclass Desktop, and be able to assign arguments into Desktop's constructor
The way you are doing it is incorrect. The types stored in the object array are of type Hardware. You can only successfully dynamic_cast those values to Hardware or anything that Hardware inherits (which is nothing).
Assuming Desktop is a subclass of Hardware (you did not actually show it), then dynamic_cast<Desktop*>(&object[0]) is guaranteed to return nullptr.
The way arrays work is they allocate memory to store a specific data type arranged sequentially in memory. You cannot expect to just treat that data type as a derived type that might (and in your case, does) contain more data.
If you wish to have an array of arbitrary hardware items, you will need to store each item as a pointer:
Hardware** object = new Hardware*[100];
std::fill(object, object + 100, NULL);
object[0] = new Desktop;
Your friend was correct, but you failed to change the type of object to store pointer types. That's what the compiler error is telling you.
At this stage, I highly recommend you use std::vector instead of allocating and managing that memory:
std::vector<Hardware*> object(100);
object[0] = new Desktop;
Even better still, use smart pointers:
// Example with shared pointers
std::vector<std::shared_ptr<Hardware>> object;
object.emplace_back(std::make_shared<Desktop>(/* args */));
// Example with unique pointers
std::vector<std::unique_ptr<Hardware>> object;
object.emplace_back(std::make_unique<Desktop>(/* args */));
You misunderstood what dynamic casting does.
Example of use:
Say you have two classes Square and Circle and both of them inherit from class Shape.
A producer creates either a Square or a Circle but passes you a pointer to a Shape.
Then via dynamic casting you can try and convert the pointer to Shape to a pointer Circle. If the Producer made a Square then the casting will fail return nullptr. If it was indeed a Circle then you will get a pointer to Circle.
In your case you create Shape and try to use dynamic casting to convert the pointer to a Square... it doesn't work this way.
I'm building a small framework in C++ which contains objects which are stored in an STL container as unique_ptr to their interface. I thought unique_ptr was the best choice as the container is supposed to be the sole owner of the objects.
I wanted to retrieve a reference to the pointed object from the container to pass to the caller. But when I get the pointer I need to dereference it to pass a reference of the content from my function which of course doesn't work on an abstract class.
I do not want to pass the raw pointer which would defy the whole concept I was developing.
I cannot cast as I cannot know the concrete type of the stored object.
The only solution it came to my mind which is reasonable enough is to store a shared pointer in the container and pass a weak pointer to the caller but if you know some other way to obtain the same result it would be great.
This is a basic code structure, with Base being an abstract class:
class Container
{
vector<unique_ptr<Base>> m_C;
public:
Base& GetBase(int index)
{
return *(m_C.at(index)); //This do not compile as Base is abstract
}
};
EDIT:
I'm not sure what more do you need as an example. The main will look like this
int main() {
Container X;
// Fill X here
A tmp = X.get(10) // Let's say I want the tenth element
}
Compiling on OSX with clang I get this error
variable type 'MXIO::MXEvent' is an abstract class
EDIT2: Problem solved
I solved the issue. The problem was not in the way the function was returning but in the way I was catching the return. I was using
auto tmp = X.get(10)
Assuming auto would take care of taking the reference while I should have been using
auto&& tmp = X.get(10)
Your interesting design works perfectly well !
Using the example as you displayed it, and using a simple Base:
the Container code compiled without any error;
the calling code compiled also without any error.
So the error is not reproductible with your snippet. And your design works as intended.
Real problem unrelated to your design
Looking at the error message, the problem appears to be very different and not related at all to the unique_ptr. I
If MXIO::MXEvent is Base, the message says that Baseis an abstract class. In fact, when adding a pure virtual function to my simple Base, I managed to reproduce your error message:
Base tmp = X.get(10); // tmp should be a full tmp object copy constructed from returned value
// But we CANNOT instantiate an abstract object !!
Note that fortunately your base class is abstract and you got an error message. With a concrete base class it would have compiled well but the object would have been sliced !
If you don't want to loose polymorphism of your abstract class you have to make tmp a reference:
Base &c = test.GetBase(4); // here the reference is copied and no new object is instantiated.
// c still reffers to the original concrete derived object.
Note that while auto&& works well, Base&& doesn't because a reference is returned.
As suggested by Christophe I will post the solution of the problem I had as an answer:
The problem was not in the way the function was returning its result but in the way I was catching the result.
int main() {
Container X;
// Fill X here
A tmp = X.get(10) // Let's say I want the tenth element
}
As Christophe pointed out the problem with this code is that tmp is not a reference to the returned object but a concrete object which of course cannot be instantiated as the base class is abstract.
In this case one should catch the return itself by reference
int main() {
Container X;
// Fill X here
A& tmp = X.get(10) // Let's say I want the tenth element
}
For a system I need to convert a pointer to a long then the long back to the pointer type. As you can guess this is very unsafe. What I wanted to do is use dynamic_cast to do the conversion so if I mixed them I'll get a null pointer. This page says http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc05keyword_dynamic_cast.htm
The dynamic_cast operator performs
type conversions at run time. The
dynamic_cast operator guarantees the
conversion of a pointer to a base
class to a pointer to a derived class,
or the conversion of an lvalue
referring to a base class to a
reference to a derived class. A
program can thereby use a class
hierarchy safely. This operator and
the typeid operator provide run-time
type information (RTTI) support in
C++.
and I'd like to get an error if it's null so I wrote my own dynamic cast
template<class T, class T2> T mydynamic_cast(T2 p)
{
assert(dynamic_cast<T>(p));
return reinterpret_cast<T>(p);
}
With MSVC I get the error "error C2681: 'long' : invalid expression type for dynamic_cast". It turns out this will only work with classes which have virtual functions... WTF! I know the point of a dynamic cast was for the up/down casting inheritance problem but I also thought it was to solve the type cast problem dynamically. I know I could use reinterpret_cast but that doesn't guarantee the same type of safety.
What should I use to check if my typecast are the same type? I could compare the two typeid but I would have a problem when I want to typecast a derived to its base. So how can I solve this?
dynamic_cast can be used only between classes related through inheritance. For converting a pointer to long or vice-versa, you can use reinterpret_cast. To check whether the pointer is null, you can assert(ptr != 0). However, it is usually not advisable to use reinterpret_cast. Why do you need to convert a pointer to long?
Another option is to use a union:
union U {
int* i_ptr_;
long l;
}
Again, union too is needed only seldom.
I've had to do similar things when loading C++ DLLs in apps written in languages that only support a C interface. Here is a solution that will give you an immediate error if an unexpected object type was passed in. This can make things much easier to diagnose when something goes wrong.
The trick is that every class that you pass out as a handle has to inherit from a common base class.
#include <stdexcept>
#include <typeinfo>
#include <string>
#include <iostream>
using namespace std;
// Any class that needs to be passed out as a handle must inherit from this class.
// Use virtual inheritance if needed in multiple inheritance situations.
class Base
{
public:
virtual ~Base() {} // Ensure a v-table exists for RTTI/dynamic_cast to work
};
class ClassA : public Base
{
};
class ClassB : public Base
{
};
class ClassC
{
public:
virtual ~ClassC() {}
};
// Convert a pointer to a long handle. Always use this function
// to pass handles to outside code. It ensures that T does derive
// from Base, and that things work properly in a multiple inheritance
// situation.
template <typename T>
long pointer_to_handle_cast(T ptr)
{
return reinterpret_cast<long>(static_cast<Base*>(ptr));
}
// Convert a long handle back to a pointer. This makes sure at
// compile time that T does derive from Base. Throws an exception
// if handle is NULL, or a pointer to a non-rtti object, or a pointer
// to a class not convertable to T.
template <typename T>
T safe_handle_cast(long handle)
{
if (handle == NULL)
throw invalid_argument(string("Error casting null pointer to ") + (typeid(T).name()));
Base *base = static_cast<T>(NULL); // Check at compile time that T converts to a Base *
base = reinterpret_cast<Base *>(handle);
T result = NULL;
try
{
result = dynamic_cast<T>(base);
}
catch(__non_rtti_object &)
{
throw invalid_argument(string("Error casting non-rtti object to ") + (typeid(T).name()));
}
if (!result)
throw invalid_argument(string("Error casting pointer to ") + typeid(*base).name() + " to " + (typeid(T).name()));
return result;
}
int main()
{
ClassA *a = new ClassA();
ClassB *b = new ClassB();
ClassC *c = new ClassC();
long d = 0;
long ahandle = pointer_to_handle_cast(a);
long bhandle = pointer_to_handle_cast(b);
// long chandle = pointer_to_handle_cast(c); //Won't compile
long chandle = reinterpret_cast<long>(c);
// long dhandle = pointer_to_handle_cast(&d); Won't compile
long dhandle = reinterpret_cast<long>(&d);
// send handle to library
//...
// get handle back
try
{
a = safe_handle_cast<ClassA *>(ahandle);
//a = safe_handle_cast<ClassA *>(bhandle); // fails at runtime
//a = safe_handle_cast<ClassA *>(chandle); // fails at runtime
//a = safe_handle_cast<ClassA *>(dhandle); // fails at runtime
//a = safe_handle_cast<ClassA *>(NULL); // fails at runtime
//c = safe_handle_cast<ClassC *>(chandle); // Won't compile
}
catch (invalid_argument &ex)
{
cout << ex.what() << endl;
}
return 0;
}
Remember that in Windows 64, a pointer will be a 64-bit quantity but long will still be a 32-bit quantity and your code is broken. At the very least, you need to make the choice of integer type based on the platform. I don't know whether MSVC has support for uintptr_t, the type provided in C99 for holding pointers; that would be the best type to use if it is available.
As for the rest, others have addressed the why's and wherefore's of dynamic_cast vs reinterpret_cast sufficiently.
reinterpret_cast is the correct cast to use here.
This is pretty much the only thing it can do safely.
reinterpret_cast from a pointer type to a type T and back to the original pointer type yields the original pointer. (Assuming T is a pointer or integer type that is at least as big as the original pointer type)
Note that reinterpret_cast from a pointer type to T is unspecified. There are no guarantees about the value of the T type, except that if you then reinterpret_cast it back to the original type, you get the original value. So assuming you don't try to do anything with the intermediate long value in your case, reinterpret_cast is perfectly safe and portable.
Edit: Of course this doesn't help if you don't know at the second cast, what the original type was. In that case,you're screwed. The long can't possibly in any way carry type information about which pointer it was converted from.
You can use reinterpret_cast to cast to an integral type and back to the pointer type. If the integral type is large enough to store the pointer value, then that conversion will not change the pointer value.
As others already say, it is not defined behavior to use dynamic_cast on a non-polymorphic class (except when you do an upcast, which is implicit anyway and be ignored here), and it also only works on pointers or references. Not on integral types.
You better use ::intptr_t found in on various posix systems. You can use that type as your intermediate type you cast to.
Regarding your check whether the conversion will succeed, you can use sizeof:
BOOST_STATIC_ASSERT(sizeof(T1) >= sizeof(T2));
will fail at compile time if the conversion couldn't be done. Or continue to use assert with that condition, and it will assert at run-time instead.
Warning: This won't prevent you from casting T* to intptr_t back to U* with U another type than T. Thus, this only guarantees you the cast won't change the value of the pointer if you cast from T* to intptr_t and back to T*. (Thanks to Nicola pointing out you may expect another protection).
What you want to do sounds like a really bad and dangerous idea, but if you MUST do it (i.e. you're working in a legacy system or on hardware that you know will never change), then I would suggest wrapping the pointer in some kind of simple struct that contains two members: 1) a void pointer to your object instance and a string, enum, or some other kind of unique identifier that will tell you what to cast the original void* to. Here's an example of what I meant (note: I didn't bother testing this so there may be syntactical errors in it):
struct PtrWrapper {
void* m_theRealPointer;
std::string m_type;
};
void YourDangerousMethod( long argument ) {
if ( !argument )
return;
PtrWrapper& pw = *(PtrWrapper*)argument;
assert( !pw.m_type.empty() );
if ( pw.m_type == "ClassA" ) {
ClassA* a = (ClassA*)pw.m_theRealPointer;
a->DoSomething();
} else if (...) { ... }
}
dynamic_cast<> is a cast intended to be used only on convertible types (in the polymorphic sense). Forcing the cast of a pointer to a long (litb correctly suggests the static_assert to ensure the compatibility of the size) all the information about the type of the pointer are lost. There's no way to implement a safe_reinterpret_cast<> to obtain the pointer back: both value and type.
To clarify what I mean:
struct a_kind {};
struct b_kind {};
void function(long ptr)
{}
int
main(int argc, char *argv[])
{
a_kind * ptr1 = new a_kind;
b_kind * ptr2 = new b_kind;
function( (long)ptr1 );
function( (long)ptr2 );
return 0;
}
There's no way for function() to determine the kind of pointer passed and "down" cast it to the proper type, unless either:
the long is wrapped by an object with some information of the type.
the type itself is encoded in the referenced object.
Both the solutions are ugly and should be avoided, since are RTTI surrogates.
also, better use size_t instead of a long -- I think this type is ensured to be compatible with the size of the address space.
As soon as you decided to cast a pointer to a long, you threw type safety to the wind.
dynamic_cast is used to cast up & down a derivation tree. That is, from a base class pointer to a derived class pointer. If you have:
class Base
{
};
class Foo : public Base
{
};
class Bar : public Base
{
};
You can use dynamic_cast in this way...
Base* obj = new Bar;
Bar* bar = dynamic_cast<Bar*>(obj); // this returns a pointer to the derived type because obj actually is a 'Bar' object
assert( bar != 0 );
Foo* foo = dynamic_cast<Foo*>(obj); // this returns NULL because obj isn't a Foo
assert( foo == 0 );
...but you can't use dynamic cast to cast in to an out of a derivation tree. You need reinterpret_cast or C-style casts for that.