Объект типа Child*
не может быть привязан к Parent*&
по той же причине, по которой Child**
не может быть преобразован в Parent**
. Разрешение этого позволит программисту (намеренно или нет) нарушать безопасность типов без приведения.
class Animal {};
class DangerousShark : public Animal {};
class CuteKitten : public Animal {};
void f(Animal*& animalPtrRef, Animal* anotherAnimalPtr)
{
animalPtrRef = anotherAnimalPtr;
}
void g()
{
DangerousShark myPet;
CuteKitten* harmlessPetPtr;
f(harmlessPetPtr, &myPet); // Fortunately, an illegal function call.
}
Редактировать
Я думаю, что некоторая путаница возникает из-за свободного употребления слов «преобразовать» и «преобразование».
Ссылки не могут быть восстановлены, в отличие от объектов, которые могут быть переназначены, поэтому в контексте ссылок, когда мы говорим о преобразовании, нас может беспокоить только инициализация новой ссылки.
Ссылки всегда связаны с объектом, и из вопроса ОП было ясно, что он стремится получить ссылку, которая является прямой связью с существующим объектом. Это допустимо только в том случае, если объект, использованный для инициализации ссылки, совместим со ссылкой с типом ссылки. По сути, это только в том случае, если типы одинаковы, или тип объекта определяется на основе типа ссылки, а тип ссылки по меньшей мере такой же квалифицированный как cv, что и объект инициализации. В частности, указатели на разные типы не являются ссылочно-совместимыми, независимо от отношения указанных типов.
В других случаях ссылка может быть инициализирована чем-то, что может быть преобразовано в тип ссылки. В этих случаях, однако, ссылка должна быть постоянной и не изменчивой, и преобразование создаст временный объект, и ссылка будет привязана к этому временному, а не к исходному объекту. Как уже отмечалось, это не подходит для требований мотивирующего примера ОП.
Таким образом, Child
может быть напрямую связан с Parent&
, но Child*
не может быть напрямую связан с Parent*&
. Parent* const&
можно инициализировать с помощью Child*
, но ссылка на самом деле будет привязана к временному Parent*
объекту, инициализированному копией из Child*
объекта.