Casting a pointer to a sub-class (C++) - c++

I'm developing a game and I need to find a way of getting the value of a certain 'map block' in the game (in char format). I have a class DisplayableObject which takes care of all sprites, and a sub-class ThreeDCubePlayer which takes care of the player object. For ease of rendering/updating everything, all DisplayableObjects are stored in an array, with the 0th cell containing the player (which is of type ThreeDCubePlayer). ThreeDCubePlayer has a different constructor from DisplayableObject (it takes two additional arguments) and only ThreeDCubePlayer has the GetMap() functions that I need. So, here is what I have done so far:
ThreeDCubePlayer* cubePlayer = &((ThreeDCubePlayer &)m_ppDisplayableObjects[0]);
char mapEntry = GetMapEntry((int)*(cubePlayer->GetMapX()), (int)*(cubePlayer->GetMapY()));
This is the part of ThreeDCubeGame.cpp (the function which controls the map and keyboard input). The problem I've had is that both of these lines give an 'illegal indirection' error at compilation. I thought this error is when I try to dereference something that isn't a pointer, and I'm sure cubePlayer looks like a pointer...
Does anyone have an idea as to what I should do?

Use one of the type safe casts, e.g. dynamic_cast instead of the C-style cast.
If m_ppDisplayableObjects is a DisplayableObject**, then it would look something like this:
ThreeDCubePlayer* cubePlayer = dynamic_cast<ThreeDCubePlayer*>(m_ppDisplayableObjects[0]);
if (cubePlayer != NULL)
{
char mapEntry = GetMapEntry(cubePlayer->GetMapX(), cubePlayer->GetMapY());
}
else // Not a ThreeDCubePlayer* ...

A couple of suggestions:
Don't use the C-style casts, use proper C++ casts instead. In your case, as you're casting down the inheritance hierarchy, you should be using dynamic_cast instead of the sledgehammer C-style cast. This will incur a small runtime overhead but it'll also make the whole thing type safe inasmuch as it isn't going to do something nasty behind your back simply because you're treating a chunk of $deity_knows_what as a ThreeDCubePlayer. Assuming that your m_ppDisplayableObjects array actually holds pointers, it'll look like this:
ThreeDCubePlayer *cubePlayer = dynamic_Cast<ThreeDCubePlayer *>(m_ppDisplayableObjects[0])
if (cubePlayer) { // Important, if you don't check for 0 here you might dereference a null pointer
... cubePlayer->GetMapX() ...
Also, if you have to cast the result of the GetMapX then you have an impedance mismatch that you should sort out somewhere else; I'd recommend either adjusting the return type of GetMapX or the parameters passed to GetMapEntry. Usually, having to wildly cast about is a sign of a design issue - well-designed C++ code should not require a lot of casts and especially not a lot of C-style casts.

Your cast is wrong, and I think the second line requires no cast at all (depends on how the methods are defined).
It should be:
ThreeDCubePlayer* cubePlayer = (ThreeDCubePlayer*)m_ppDisplayableObjects[0];
char mapEntry = GetMapEntry( cubePlayer->GetMapX(), cubePlayer->GetMapY() );
The cast in the first line should also be a C++ style cast, e.g.:
ThreeDCubePlayer* cubePlayer = static_cast<ThreeDCubePlayer*>(m_ppDisplayableObjects[0]);

Be aware that in a game application, having a situation where you end up doing zillions of dynamic_casts per game frame can negatively impact performance. You'll usually find people doing other solutions to determine how to recast a object pointer stored in a container to the appropriate object type using static_cast or C style casting rather than relying on RTTI. Depending on the number of object types and other factors, there are various ways of doing this, but a simple method is just to have a enum class id and a get method for each of the enum types that returns null if the class id doesn't match the one being requested.

For the first line, you can cast the DisplayableObject to the derived class ThreeDCubePlayer type using dynamic_cast.
ThreeDCubePlayer* cubePlayer = dynamic_cast<ThreeDCubePlayer*> (m_ppDisplayableObjects[0]);
For the second line, you're dereferencing whatever is returned by ThreeDCubePlayer::GetMapX(). If that function doesn't return a pointer (or some class with an overloaded * operator), you'll get a compilation error.

You haven't given much code to go on, but I think your first line should be:
ThreeDCubePlayer* cubePlayer = (ThreeDCubePlayer *) m_ppDisplayableObjects[0]);
We'd need to see the declaration of GetMapX() to know about the second line.

ppDisplayableObjects is an array or base pointers isn't it?
so try this?
const ThreeDCubePlayer* const cubePlayer = m_ppDisplayableObjects[0];
char mapEntry = GetMapEntry( cubePlayer->GetMapX(), cubePlayer->GetMapY() );
GetMapX etc. ought to return an (unsigned) int? and not a pointer to an int? (no negs? so unsigned?)
I'd like to second everyone else's comments on casting, they're a sign that your hierachy is not working quite right, but... but if you do have to cast then thinking about which C++ cast you'd need to use is a useful exercise, it also means when you want to revisit/tighten up your code all the casts are easier to search out and remove
ps - rack up your constness too where you can
and add the arrays etc to some sort of owner class, maybe a singleton if you know you've only got the one
also IMHO... (sorry) write yourself a Coords class so that you can do things like GetMapEntry(const Coords& coords) instead of getting the x and the y values separately, this'll save you getting them swapped round the wrong way etc.
:)

Related

Can list cast correctly in Kotlin?

I am new to Kotlin,
data class RewardDetail(
val name: String
val isActivated: Boolean
val amountInCents: Int?
val Campain: String?
val expirationDate: Long?
)
class Rewards(Array<Reward>)
class Reward(
    val name: String
   
isActive: Boolean
   
amountInCents: Int
    campaignId: String
    expirationDate: LocalDateTime
)
val details : List<RewardDetail> = blablabla
val rewards = Rewards(details)
can details cast to rewards successfully?
Also note campaignId and Campain field name are different in RewardDetail and Reward and some fields can be nullable in RewardsDetail
What is the best way to handle situation like this?
Kotlin is strongly-typed. You can never successfully cast one thing into a different class. You can only cast an object into a type that it already satisfies. For example, if you have an Int that is currently only known to the compiler to be a Number, you can cast to Int to tell the compiler that it has an Int, so the compiler will allow you to use the functions that are specific to Int. But nothing but an Int can ever be cast to an Int.
So, unlike weakly typed languages, casting does not convert from one type to another. Casting is only you making a promise to the compiler that an object already is of the other type.
In your example, the only way to get a RewardDetail from a Reward is by writing a function that manually converts each property to the appropriate type.
The Rewards class above is largely redundant. There's no need for a wrapper class around a single Array or List unless you need to do validation of items added to or retrieved from the list. In that case, it would probably make more sense to create a subclass of ArrayList for that purpose, so you could still easily iterate the list and use all the List and Iterable helper functions on it.
Probably about 95% of the time, you should prefer using List over using Array. Arrays should be used only when you need a fixed size collection that is also mutable, or if you are working with highly performance-critical code. The reason it should be limited to these uses is that mutability should be avoided when possible for robustness and Arrays are more cumbersome to work with than MutableLists.
A typical implementation of a function that converts from one type to another would be to write an extension function RewardDetail.toReward() extension function, or a toReward() function inside the RewardDetail class. However, in your case you need to decide what you need to happen when some of the values of RewardDetail are null. Maybe you just return null so your conversion function should be toRewardOrNull(), or you provide default values for the properties that have no value in RewardDetail.

QByteArray conversion and pointer casting

I'm working with Qt and C++. I have to manage error codes of an electronic board. I can get these errors in the form of QByteArray that I have to convert into a QVariant. I did not find any practial method to do this (so if you have one I'm here listening).Anyway, trying to convert it (the QByteArray) to the QVariant, the only method I found is to use a code like this:
QByteArray value; //This is the QByteArray where I have the error code
QVariant qVariantOut; //This is the QVariant where I want to put the error
qVariantOut = QVariant(*(quint64*)(void*)(&(value).data()[0]));
Because of the bad casting steps I used, I have stumbled upon the various good casting rules and I did somethig like this:
qVariantOut = QVariant(*(static_cast<quint64*(static_cast<void*>((&(value).data()[0]))));
These casts seem to work and so I decided to deepen the casting subject but I don't understand some results I got. Following I present all the cases I have tried. If someone could give me an explanation (I'll present mine) of what is happening in each case it would be great.
qVariantOut = QVariant(*((quint64 *)value.data()));
I think this works because value.data() returns a char* and the cast quint64* do a reinterpret_cast (if I interpreted well what it is said here: When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? ). Is this reason correct?
qVariantOut = QVariant(*(static_cast<quint64*>(value.data()) ));
This one does't work because I'm trying to do a static_cast directly to an quint64*. But here I have one question: why it is not possible to cast from char* to quint64*. Aren't them some basics (POD) type for which a static_cast have to be possible?
I would like to understand better these casts... I even find someone that said: "if you need to cast pointers, cast them via void*". Comments?
qVariantOut = QVariant( (quint64*)(value.data()) );
This is something like a bonus. I'm trying with this code to put in a QVariant a pointer... This give me the error "QVariant::QVariant(void) is private within this context*" and I don't get what this means.
Thank you.
EDIT: For the users that said it could be an XY problem. Here are some more information. I wrote a function to get variables from an electronic board. These variables could be QString, quint64, qint32, quint8 and so on...In my function, in order to get these variables, I use an external function (coming from an external library, developed internally by the electronic division of my company, I have to use it but can't modify it). In order to use this external function I need to pass as parameters: the variable I want to read (i.e.: errors, warnings, temperatures, version of firmware...), an output QByteArray and the size of the variable I want to read(for example errors->sizeof(quint64), temperatures->sizeof(quint8)). This external function, as you understand, returns a QByteArray.
The fact that I present the code with a cast to quint64 is only a case of my function.
I want to convert this QByteArray to a QVariant so my function can return this qVariantOut that I will convert to the correct variable (for example: I know that I need to read the error variable of the board, I call my function that will set the variable size and pass it to the external function (together with the variable name) that will return a QByteArray. This QByteArray will be converted in a QVariant returned outside my function. Outside I will convert the QVariant to the right variable for example a quint64 for the errors, using QVariant methods). Note that I do this because of the constraint of the system (I need to use that external function that returns always a QByteArray for every type of variable I want to read) and because I did not find a better and more practical method to convert a QByteArray to the final variable (ex.: if I use qba.toLongLong, with qba a QByteArray, it doesn't work)... if you have one, as I said before, I'm here listening to you.
Anyway I don't want to focus too much on the XY problem (but if it is an XY problem I want to resolve it obviously) but I want to understand better that casting rules and to have a constructive discussion on my doubt and questions :)
With your updates, this isn't quite as crazy as it first seemed. It is kinda crazy that you have an internal API putting random variables into a QByteArray rather than something like QVariant which is exactly what it is made for, but I get that you are stuck with what you have.
You have two options:
Cast, but there's no need to do anything complicated, just use reinterpret_cast. Casting to void* then back to something else with static_cast is the same thing as a reinterpret_cast, so you might as well just call reinterpret_cast to start with.
memcpy(&target, byteArray.data(), sizeof(target)); This avoids the casting, but is almost as ugly. In theory, its a little safer in light of memory alignment issues (don't have to rely on the data in your QByteArray being the right alignment to reinterpret_cast). It also lets you hold on to the data as long as you want without risking the internal pointer in the QByteArray being reclaimed behind your back.
Note that both of these options only work with POD types, but I assume other than QString everything you're getting back is, and for QString you'd have to make a special case depending on the encoding (pretty simple if is ASCII/Latin1).
As for why you can't static_cast directly from char* to quint64*, that isn't a static_cast. You can't static cast between distinct types, only related types, like between base* and a class that derives from base. There's a good explanation of static_cast's limited use case in this answer by EdChum.

Align A Pointer To Have A Functional -> Operator? C++

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 *

The ** idiom in C++ for object construction

In a lot of C++ API'S (COM-based ones spring to mind) that make something for you, the pointer to the object that is constructed is usually required as a ** pointer (and the function will construct and init it for you)
You usually see signatures like:
HRESULT createAnObject( int howbig, Object **objectYouWantMeToInitialize ) ;
-- but you seldom see the new object being passed as a return value.
Besides people wanting to see error codes, what is the reason for this? Is it better to use the ** pattern rather than a returned pointer for simpler operations such as:
wchar_t* getUnicode( const char* src ) ;
Or would this better be written as:
void getUnicode( const char* src, wchar_t** dst ) ;
The most important thing I can think of is to remember to free it, and the ** way, for some reason, tends to remind me that I have to deallocate it as well.
"Besides wanting error codes"?
What makes you think there is a besides. Error codes are pretty much the one and only reason. The function needs some way to indicate failure. C doesn't have exceptions, so it has to do that through either a pointer parameter, or the return value, and the return value is idiomatic, and easier to check when calling the function.
(By the way, there's no universal rule that ** means you have to free the object. That's not always the case, and it's probably a bad idea to use something that arbitrary to remind you of which objects to clean up.)
Two reasons come to my mind.
First are error codes actually. Other than C++, C doesn't have exceptions, and COM is a C-API. Also many C++ based projects prefer not to use exceptions for various reasons.
There may be cases, where a return value can't signal errors, E.g. if your function returns an integer, there may be no integer value, that can represent an error code. While signalling errors with pointers is easy (NULL == Error), some API designers prefer to signal errors in a consistent way over all functions.
Second, functions can have only one return value, but calling them may create multiple objects. Some Win32 API functions take multiple pointers to pointers that can be filled optionally, if you call these functions with non-NULL pointers. You cannot return two pointers, or rather this would be awkward to use, if the return value is some struct by value containing more than one pointer. Here too a consistent API is a sensible goal to achieve.
New objects in function arguments passed by ** is better. This take me a comfort to future use of change void to bool for example to return success of a function or other information providing function works.
Answer in one line: This is much better for resulting error codes.
Besides people wanting to see error codes, what is the reason for this?
There are some reasons for this. One of them is writing an interface that is usable in C (you see this in the WinAPI and Windows COM).
Backwards compatibility is another reason (i.e. the interface was written like that and breaking it now would break existing code).
I'd go with C compatibility for a design principle when using code like this. If you were to write in C++ you'd write
retval Myfunction(Result *& output);
instead of
retval Myfunction(Result ** output);
or (even better):
Result *Myfunction();
and have the function throw an exception on error.
I'm not sure I agree that's the best way to do it... this might be better:
Object * createAnObject(int howbig, HRESULT * optPlaceResultCodeHereIfNotNull = NULL);
That way there is no messing about with double-indirection (which can be a little bit tricky for people who aren't used to it), and the people who don't care about result codes don't have to worry about the second argument at all... they can just check to see if the return value is NULL or not.
Actually, since it's C++, you could make things easier still, using function overloading:
Object * createAnObject(int howbig);
Object * createAnObject(int howbig, HRESULT & returnResultCode);
Any method call in a COM call has to be HRESULT. The return codes get leveraged all over the framework and passing a double pointer is a well-known way to get the created object.
Not answering your question but a comment as your question brought out some thoughts I have about COM/DCOM programming using C++.
All these "pointer" and "pointer to pointer", memory management and reference counting are the reasons why I shy away from doing COM programming with C++. Even with ATL in place, I dislike it for the simple reason that it does not look natural enough. Having said that, I did do a few projects using ATL.
Back then the alternative is use VB. VB code looks more natural for COM or DCOM programming.
Today, I would use C#.

casting a pointer in Run Time [non-trivial Scnerio]

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 ;)