c# - 静态绑定(bind)期间 C++ 和 Ada 的差异

标签 c# c++ binding ada

我正在做作业,遇到了这个问题:

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()

调用basederived 的方法会产生明显的结果。在 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_VarDerived_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/

相关文章:

c# - 逐步加载多页 t​​iff 的 WPF 图像控件

c# - 在特定设备中播放声音

c++ - 内存重用实际是什么意思?

c++ - 如何在like查询中使用sqlite icu

c# - 将绑定(bind)从 C# 转换为 XAML

c# - 如何计算其他国家的时间。在 C# 中使用我的本地机器时间?

c# - 拖放数据网格

c++ - 如何将外部库与 CMake 项目链接

macos - 无法在 Swift Storyboard 中设置绑定(bind)?

c# - 将通用集合 List<> 绑定(bind)到属性网格