无法向上转换指针到指针参数



我在这里什么都听不懂。我希望如果我可以将狗指针传递给获取动物指针的函数,我也可以将 &dog 传递给一个将指针传递给动物指针的函数。

struct Animal{};
struct Dog : Animal{};
void ptrToPtr(Animal** arg){}
void refToPtr(Animal*& arg){}
void refToConstPtr(Animal* const & arg){}
void ptrToConstPtr(Animal* const * arg){}
int main(void)
{
Dog* dog;
Animal* animal;
ptrToPtr(&animal); // Works
ptrToPtr(&dog); // Argument of type Dog** is incompatible with argument of type Animal**
refToPtr(animal); // Works
refToPtr(dog);      // A reference of type Animal*& (not const-qualified) cannot be initialized with a value of type Dog*
ptrToConstPtr(&animal); // Works
ptrToConstPtr(&dog);    // Argument of type Dog** is incompatible with paramater of type Animal* const*
refToConstPtr(animal); // Works
refToConstPtr(dog);  // Works. This is the only one that allows me to send Dog to Animal
return 0;
}

我只是不明白,谁能解释一下为什么特定情况有效而其他情况无效的原因是什么?就像将狗的指针地址传递给动物**一样,那将是一个向上的投掷,不是吗?

相互转换的指针类型是指向派生/基类型的对象的指针。"指向指针的指针"不能与其他类型相互转换(void*除外(。这同样适用于引用。

这意味着给定以下任何层次结构:

struct Animal{};
struct Dog : Animal{};

以及以下变量:

Dog* dptr;
Animal* aptr;

dptr可以转换为Animal*(甚至是隐式(,同样aptr也可以转换为Dog*(但不能隐式(。因为:在类层次结构中向上转换始终是合法的,因此这将由 ICS 隐式完成。但是,向下投射并不总是如此,因此它从未隐式地完成(

然而:

Dog** ddptr;
Animal** aaptr;

ddptr不能隐式转换为Animal**,同样aptr也不能转换为Dog**。因为,它们是两种不同的类型,没有等级关系。




上面的解释解释了指针指向指针重载失败的原因。 也就是说,让我们处理引用类型重载。从您的代码中,

refToPtr(animal); // Works
refToPtr(dog);      // A reference of type Animal*& (not const-qualified) cannot be initialized with a value of type Dog*

第二个调用不起作用,因为X的非常量引用只能绑定到X的精确glvalue对象。由于refToPtr接受对Animal*类型的非常量引用,因此我们只能向它传递Animal*类型的 gl值,animal是,但dog不是。

最后一个有效,它是合法的,因为

refToConstPtr(animal); // Works
refToConstPtr(dog);    // Works. This is the only one that allows me to send Dog to Animal

constX的引用可以绑定到任何X值类别,包括寿命延长的临时性。因为我们可以dog转换为Animal*.该转换将发生,并生成一个临时Animal*,其生存期通过const引用延长。

最新更新