无法将指针转换为指针参数

时间:2017-08-27 13:00:54

标签: c++ pointers inheritance upcasting

我在这里无法理解任何事情。我期望如果我可以将狗指针传递给使用动物指针的函数,我也可以将& dog传递给一个带有指向Animal指针的函数。

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

我只是没有得到它,任何人都可以解释为什么特定案例有效的原因和其他人没有?就像将狗指针地址传递给动物**一样,这将是一个向上的,不会吗?

1 个答案:

答案 0 :(得分:3)

可互换的指针类型是指向派生/基类型对象的指针。 “指针指针”与其他类型可互换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 对象。由于refToPtrAnimal*类型采用非const引用,因此我们只能传递Animal*类型的glvalues,animal是{,} {}} “T

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

dog

refToConstPtr(animal); // Works refToConstPtr(dog); // Works. This is the only one that allows me to send Dog to Animal const的引用可以绑定到X的任何值类别,包括其生命周期延长的temproaries。由于我们可以将X转换为dog。进行转换并生成临时Animal*,其生命周期由Animal*引用扩展。