假设我有一个指向ICScannerDevice
类的指针,我为其分配了一些内存。现在,我想用ICDevice
类型的指针初始化它,它是ICScannerDevice
的父类。
我该怎么做?
以下是正确的方法吗?我猜不是!
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.
答案 0 :(得分:3)
假设我有一个指向ICScannerDevice类的指针,我为其分配了一些内存。
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
你在这里混合两件事。 变量由声明创建,声明也可以包含初始化表达式。
当您声明分配的变量空间可以包含变量 的值时 - 该类型是否为int
,在哪种情况下,该值将是整数,例如42
或ICScannerDevice *
,在这种情况下,该值将是对已分配的ICScannerDevice
对象的引用。
声明:
ICScannerDevice* scannerDevice
提供存储类型ICScannerDevice *
值所需的所有空间。你给出的初始化表达式:
[[ICScannerDevice alloc] init];
在您的情况下是多余的(并且浪费),您不希望创建ICScannerDevice
类型的对象并在scannerDevice
中存储对该对象的引用,因为您希望存储完全不同的引用在你的变量中:
现在,我想用ICDevice类型的指针初始化它,ICDevice是ICScannerDevice的父类。
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.
这是错误的,因为您声明device
拥有对ICDevice
对象的引用。由于类型ICDevice
是ICScannerDevice
的父级,因此对ICScannerDevice
的引用可以视为ICDevice
- 也就是&#34; upcast&#34;。< / p>
但是,已知为ICDevice
类型的对象的引用可能是ICScannerDevice
,也可能不是ICPlotterDevice
,可能是ICScannerDevice
。所以你不能直接演员 - aka&#34; downcast&#34;并指派。
您必须首先检查您是否确实引用了isKindOfObject:
。您可以通过使用方法ICScannerDevice
检查引用对象的类型是否为class
类型,并使用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
...
}
方法获取该类型来执行此操作:
device
您还需要处理nil
中存储的值为if
的情况 - 即它不引用任何内容。您可能只想将其与ICScannerDevice
中的测试结合使用,并将其视为if ( (device == nil) || [device isKindOfObject:[ICScannerDevice class]] )
参考:
{{1}}
或者您可能需要以其他方式处理它。
HTH
答案 1 :(得分:1)
首先,如果您立即将一些其他对象分配给其参考,那么分配对象是没有意义的。
其次,如果device
不是ICScannerDevice
,那么将其拼凑为一个错误可能会也可能不会导致您出现问题,具体取决于您接下来要做什么。
所以,答案是:不,它不是真的正确。
(为了更好地回答您应该正在做什么,需要更多关于device
来自哪里以及您希望如何使用scannerDevice
的背景信息。)
答案 2 :(得分:1)
指针是一个数字,用于保存对象所在的内存地址。
指针是(16/32/64位)并且存在于堆栈中。只是它的内容在堆上。
因此,您不需要为指针分配任何空间。仅限内容。因为 - 在你的情况下 - 你得到一个指向现有内容的指针。只需复制内存地址:ICScannerDevice* = (ICScannerDevice*)device; // device is a pointer to ICDevice.
注意:请记住演员不要更改内容!如果设备不是真正的ICScannerDevice,而是其他东西,可能会在以后崩溃。