我们假设我有一个Base班级和一个Derived班级:
class Base {};
class Derived : public Base {};
Run Code Online (Sandbox Code Playgroud)
我fun现在可以明确地指定一个指向Derived内容的指针,myBase如下所示:
void fun( Base** myBase ) {
Derived* myDerived = new Derived();
*myBase = myDerived;
}
int _tmain(int argc, _TCHAR* argv[])
{
Base *myBase = NULL;
fun( &myBase );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,问题是我想要分配一个数组Base*(我不能使用typedef来掩盖三星,因为签名fun是自动生成的):
void fun( Base*** myBase ) {
Derived** myDerived = new Derived*();
*myBase = myDerived;
}
Run Code Online (Sandbox Code Playgroud)
为什么我从C2440: '=' : cannot convert from 'Derived **' to 'Base **'转换Derived*到Base*完全没问题?
答案在于基础指针实际上在C++中的作用.考虑以下简单示例:
struct A { std::uint32_t a; };
struct B { std::uint32_t b; };
struct D : A, B { std::uint32_t d; };
Run Code Online (Sandbox Code Playgroud)
这里D有两个基地,A和B.但是只有其中一个可以存在于开头D(简而言之A),所以当你将其转换D为另一个(B)时,指针的值需要改变,指向中间的D某个点.
要想象这一点,请考虑类型对象D在内存中的样子:
0 1 2 3 4 5 6 7 8 9 A B
[ A::a ][ B::b ][ D::d ]
^ a D* would point here
^ a A* would point here
^ a B* must point here
Run Code Online (Sandbox Code Playgroud)
虽然D期望所有这三个整数,但在考虑这个对象时A,我们只期望第一个,但指针是(数字上)相同的,我们只期望一个更短的对象.但是,当把它想象成一个时B,我们需要指向中间的一个整数.
当您对一个指针执行此操作时,编译器将通过适当地更改指针的值来为您处理此问题.但是,当您对指针数组执行此操作时,编译器需要在其中的所有元素上发出循环并更正每个指针 - 实际上它甚至无法知道数组的结束位置(因为编译器只看到指针到它的开始)!
因此C++不允许这种转换.
| 归档时间: |
|
| 查看次数: |
373 次 |
| 最近记录: |