Равны ли ссылки и указатели в отношении полиморфизма? - PullRequest
41 голосов
/ 01 октября 2010

Я всегда думаю о необходимости использовать указатели для полиморфизма.Используя канонический пример:

DrawEngine::render(Shape *shape)
{
    shape->draw();
    shape->visible(true);
}

И передавая указатель на различные производные от Shape классы.Работает ли это так же со ссылками?

DrawEngine::render(Shape &shape)
{
     shape.draw();
     shape.visible(true);
}

Можно ли вообще сделать следующее:

engine.render(myTriangle); // myTriangle instance of class derived from Shape

Если это работает, есть ли различия между этими двумя случаями?Я пытался найти информацию в Страуструпе, но ничего не нашел.

Я снова открыл это, потому что хотел изучить чуть больше.

Так что по крайней мере одно отличие - dynamic_cast.Для меня полиморфизм включает использование dynamic_cast.

Могу ли я пойти

Rhomboid & r = dynamic_cast<Rhomboid &>(shape);

Что произойдет, если приведение не удастся?Это что-то другое?

Rhomboid * r = dynamic_cast<Rhomboid*>(&shape);

Ответы [ 3 ]

46 голосов
/ 01 октября 2010

Что касается полиморфизма, ссылки работают так же, как указатели.

10 голосов
/ 15 октября 2010

Относительно dynamic_cast, неудачное приведение создает нулевой указатель с указателями и приводит к выбросу исключения bad_cast (IIRC) со ссылками.

Одна из причин заключается в том, что такой вещи, какдопустимая нулевая ссылка.

И, возможно, еще одна причина (но это может быть просто непреднамеренно полезная функция Emergent) заключается в том, что иногда требуется исключение, а иногда - простой в проверке нулевой указатель, и неважно,у вас есть ссылка или указатель под рукой, для получения желаемого поведения требуется не более оператора разыменования или адреса.

Cheers & hth.,

0 голосов
/ 15 октября 2010

Указатели помогают и другими способами.Как передача строки и принятие ее в качестве параметра char * в функции.

Рассмотрим старый пример перестановки строки на месте:

void reversestring(char* myString)
{
int firstPos=0;
int lastPos=myString.length - 1;
while (firstPos < lastPos)
{
  char temp=myString[firstPos];
  myString[firstPos]=myString[lastPos];
  myString[lastPos]=temp;
  firstPos++;
  lastPos--;
}
}

Написание кода для манипулирования строками, подобного этим, с использованием ссылок не будет таким простым.

...