Почему компилятор допускает использование ссылок для полиморфизма во время выполнения в C ++? - PullRequest
1 голос
/ 24 мая 2019

Меня беспокоит полиморфизм во время выполнения.Я вполне понимаю понятие использования указателей базового класса и «виртуального» ключевого слова для достижения этого.И я понимаю, почему компилятор откладывает разрешение вызовов на время выполнения.Но я смущен, думая, почему компилятор откладывает это, когда используются ссылки, а не указатели.Ссылка, однажды назначенная, не может ссылаться ни на что другое.Итак, разве компилятор уже не знает, на какой объект ссылается ссылка?Итак, почему он не разрешает статически вызовы функций при наличии ссылки на базовый класс, а не указателя? Это отличается для указателя, потому что он может указывать на любой объект во время выполнения в иерархии классов.Но ссылка исправлена!

Вот фрагмент кода:

class Base
{
protected:
   int m_value;

public:
   Base(int value)
    : m_value(value)
   {
  }

   virtual const char* getName() const { return "Base"; }
   int getValue() const { return m_value; }
};

class Derived: public Base 
{
public:
   Derived(int value)
       : Base(value)
  {
   }

virtual const char* getName() const { return "Derived"; }
};

int main()
{
   Derived derived(5);
   std::cout << "derived is a " << derived.getName() << " and has value " << 
   derived.getValue() << '\n';

Base &ref = derived;
std::cout << "ref is a " << ref.getName() << " and has value " << ref.getValue() << '\n';

Base *ptr = &derived;
std::cout << "ptr is a " << ptr->getName() << " and has value " << ptr- >getValue() << '\n';

return 0;
}

1 Ответ

2 голосов
/ 24 мая 2019

«Ссылка исправлена» предпосылка ложна.Ссылка может относиться к базовому подобъекту любого объекта в иерархии, так же как и указатель.Компилятор не может определить из ссылки, что является наиболее производным объектом, не больше, чем он может по указателю.

Рассмотрим:

void DoSomething(const Base& b) { std::cout << b.getName(); }

Base base;
DoSomething(base);  // b is bound to Base object. Prints "Base"

Derived derived;
DoSomething(derived);  // b is bound to Base subobject of Derived object.
                       // Prints "Derived"
...