Различия в C ++ и Ada во время статического связывания

Я нахожусь в середине моего задания, и я столкнулся с этим вопросом:

Предполагая, что иногда мы хотим статического связывания, вы предпочитаете метод по методу
подход C ++ и C # или подход «переменные за переменными» в Ada 95? Почему?

Я искал в Интернете и учебник, но я не мог найти, что означает метод «метод за методом» в C ++ или метод «переменная за переменной» в Ada. Может кто-нибудь сказать мне значение этих терминов и что лучше из этих двух подходов.

Заранее спасибо!

1

Решение

Давайте сначала посмотрим на пример, C ++:

class Base {
public:
void a();
virtual void b();
};

class Derived : public Base {
public:
void a();
virtual void b();
};

Base* base = new Base();
Derived* derived = new Derived();
Base* upcastedDerived = new Derived();

base->a(); // calls Base::a()
base->b(); // calls Base::b()

derived->a(); // calls Derived::a()
derived->b(); // calls Derived::b()

upcastedDerived->a(); // calls Base::a()
upcastedDerived->b(); // calls Derived::b()

Называя методы base а также derived дает очевидные результаты. На upcastedDerivedПризыв к a() связан во время компиляции (статическое связывание), поэтому он связан с Base::a() потому что переменная имеет тип Base*, Призыв к b() однако связан во время выполнения, потому что метод объявлен virtual, Потому что объект на самом деле класса Derived, Derived::b() вызывается.

Как вы видите, в C ++ от объявления метода зависит, связан ли вызов метода статически или динамически. Обратите внимание, что ключевое слово virtual в производном классе необязателен — метод автоматически является виртуальным, поскольку базовый метод, который он переопределяет, является виртуальным.

Теперь давайте сделаем что-то похожее с Ada:

procedure Dispatching is
type Base is tagged null record;

procedure A (Object : in out Base);

type Derived is new Base with null record;

overriding procedure A (Object : in out Derived);

Base_Var : Base;
Derived_Var : Derived;
Upcasted_Var : Base'Class := Derived_Var;
begin
A (Base_Var); -- calls first A() procedure
A (Derived_Var); -- calls second A() procedure
A (Upcasted_Var); -- calls second A() procedure
end Derived;

Первое, что нужно отметить: у Ады нет ключевого слова, похожего на virtual, Все методы могут быть связаны статически или динамически. Как видите, это зависит от типа переменной объекта: Base_Var а также Derived_Var оба имеют конкретный тип, и поэтому вызывается процедура этого типа. Upcasted_Varс другой стороны, имеет тип класса (это не имеет эквивалента в C ++). Поэтому третий призыв к A() связан динамически.

Подводя итог: в C ++ (и C #) есть способ аннотировать метод независимо от того, должен ли он отправляться или нет. У Ады есть способ аннотировать переменную объекта, независимо от того, должны ли вызовы ее функций отправляться или нет. Чтобы контролировать, является ли вызов диспетчеризируемым или нет, вы можете привести переменную к общеклассовому типу в Ada (вы не должны приводить к конкретному типу, чтобы предотвратить диспетчеризацию, потому что, если у вас уже есть общеклассный тип, вы не можете будь уверен, сможешь ли ты это разыграть).

Вы можете видеть это так: в C ++ любой указатель на класс является общеклассовым. В Аде любая примитивная подпрограмма тегового типа является виртуальной. Для полноты, вот как вы можете предотвратить диспетчеризацию на основе переменной в C ++:

upcastedDerived.Base::b();

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

2

Другие решения

Других решений пока нет …