我正在做作业,遇到了这个问题:
Assuming that we sometimes want static binding, do you prefer the method-by-method approach of C++ and C#, or the variable-by-variable approach of Ada 95?Why?
我在网上和教科书上搜索,但我找不到 C++ 中逐个方法的方法或 Ada 中逐个变量的方法的含义。谁能告诉我这些术语的含义以及这两种方法中哪种更好。
提前致谢!
最佳答案
让我们先看一个例子,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()
的调用在编译时绑定(bind)(静态绑定(bind)),因此它绑定(bind)到 Base::a()
因为变量的类型是 Base*
。然而,对 b()
的调用是在运行时绑定(bind)的,因为该方法被声明为 virtual
。因为该对象实际上属于 Derived
类,所以会调用 Derived::b()
。
如您所见,在 C++ 中,方法调用是静态绑定(bind)还是动态绑定(bind)取决于方法声明。请注意,派生类中的关键字 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;
首先要注意的是:Ada没有类似virtual
的关键字。所有方法都可以静态或动态绑定(bind)。如您所见,它取决于对象变量的类型:Base_Var
和 Derived_Var
都有一个具体类型,因此调用该类型的过程。另一方面,Upcasted_Var
具有类范围的类型(这在 C++ 中没有等效项)。因此,对 A()
的第三次调用是动态绑定(bind)的。
总结一下:C++(和 C#)有一种方法可以对方法进行注释,以确定它是否应该进行分派(dispatch)。 Ada 有一种方法可以向对象变量注释对其函数的调用是否应该分派(dispatch)。要控制调用是否正在调度,您可以在 Ada 中将变量转换为类范围类型(您不应该转换为具体类型以防止调度,因为如果您已经有一个类范围类型,您不能确定你是否可以施放它)。
您可以这样看:在 C++ 中,任何指向类的指针类型都是类范围的。在 Ada 中,标记类型的任何原始子程序都是虚拟的。为了完整起见,以下是如何防止基于 C++ 中的变量进行分派(dispatch):
upcastedDerived.Base::b();
我不会讨论其中哪种方法更好,因为这主要是基于意见的。
关于c# - 静态绑定(bind)期间 C++ 和 Ada 的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20025344/