Reputation: 2824
Suppose I have a pointer to type ICScannerDevice
class for which I have allocated some memory. Now, I want to initialize it with the pointer of type ICDevice
which is a parent class of ICScannerDevice
.
How do I do this?
Is the following the correct method? I guess not!
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.
Upvotes: 0
Views: 828
Reputation: 53010
Suppose I have a pointer to type ICScannerDevice class for which I have allocated some memory.
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
You are mixing two things up here. Variables are created by declarations, a declaration can also contain an initialisation expression.
When you declare a variable space is allocated which can contain a value of the variable's type - whether that type is int
, in which case the value would be a integer e.g. 42
, or ICScannerDevice *
, in which case that value would be a reference to an allocated ICScannerDevice
object.
So the declaration:
ICScannerDevice* scannerDevice
provides all the space you need to store a value of type ICScannerDevice *
. The initialisation expression you give:
[[ICScannerDevice alloc] init];
is in your case redundant (and wasteful), you do not wish to create an object of type ICScannerDevice
and store a reference to that object in scannerDevice
as you wish to store a totally different reference in your variable:
Now, I want to initialize it with the pointer of type ICDevice which is a parent class of ICScannerDevice.
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.
This is wrong as you state that device
holds a reference to an ICDevice
object. As the type ICDevice
is a parent of ICScannerDevice
a reference to an ICScannerDevice
can be treated as one to an ICDevice
- aka "upcast".
However a reference known to be an object of type ICDevice
may or may not be to an ICScannerDevice
it might be , say, to an ICPlotterDevice
. So you cannot directly cast - aka "downcast" and assign.
You must first check you actually have a reference to an ICScannerDevice
. You do this by checking whether the type of your referenced object, using method isKindOfObject:
, is the type ICScannerDevice
, and you obtain that type with the class
method:
if ( [device isKindOfObject:[ICScannerDevice class]] )
{
// we have a reference to an ICScanner Device
scannerDevice = (ICScannerDevice *)device; // downcast and assign
...
}
else
{
// device references something other than an ICScannerDevice object
// handle this case
...
}
You also need to handle the case where the value stored in device
is nil
- i.e. it references nothing. You might just want to combine this with the test in the if
and treat it as an ICScannerDevice
reference:
if ( (device == nil) || [device isKindOfObject:[ICScannerDevice class]] )
or you may need to handle it some other way.
HTH
Upvotes: 3
Reputation: 31016
First, there's no point in allocating an object if you're immediately going to assign some other object to its reference.
Second, if device
is not a ICScannerDevice
, casting it as one is an error that may or may not cause you problems depending on what you do with it next.
So, the answer is: no, it's not really correct.
(To give you a better answer about what you should be doing instead would require a little more context about where device
comes from and how you want to use scannerDevice
.)
Upvotes: 1
Reputation: 50109
a pointer is a number that holds a memory address where the object is.
a pointer is(16/32/64 bit) and lives on the stack. just its content is on the heap.
therefore, you don't need to allocate any space for a pointer. Only for the content. Since - in your case - you get a pointer to existing content. Just copy the memory address:
ICScannerDevice* = (ICScannerDevice*)device; // device is a pointer to ICDevice.
NOTE: remember casts don't change the content! if device isn't really a ICScannerDevice but something else, that might crash later.
Upvotes: 1