C++中早期绑定和后期绑定有什么区别?

4 c++ oop

因为我正在研究面向对象的编程语言,所以它比C和相当新的概念要好得多.我对早期绑定和后期绑定感到困惑,所以我的问题是

C++中早期绑定和后期绑定有什么区别?

Pix*_*ist 5

请考虑以下代码:

void foo()
{
  std::cout << "A\n";
}
void bar()
{
  std::cout << "B\n";
}

// returns a callable object which either refers to foo or bar
// depending on user input during runtime
std::function<void()> maker()
{
  std::cout << "Please give a number:\n";
  auto x = 0.0;
  if (std::cin >> x && x > 50.0)
  { // if we get a valid value from the console and if it is > 50
    // we return a callable that refers to foo
    return{ &foo };
  }
  // otherwise we return a callable that refers to bar
  return{ &bar };
}
Run Code Online (Sandbox Code Playgroud)

一个简单的调用foo或者bar可以在编译时解决(函数绑定可以在编译期间早期发生)但是使用maker()会导致后期绑定,因为编译器实际上不知道将调用哪个函数:

auto f = maker();
f(); // whether foo or bar is called depends 
     // on the user input during maker execution
Run Code Online (Sandbox Code Playgroud)

所有其他动态调度方法(即虚函数调用)也是如此.

如果编译器无法(在编译时)证明(运行时信息的缺失)在程序流的某个点调用特定函数,则使用后期函数绑定来解析运行时的相应操作.否则,早期函数绑定用于在编译时解析调用(可能不一定是实际调用,但也可以通过内联完成).


编辑:给定以下源,GCC(根据godbolt)正在执行与后期绑定-O0两者,foo并且bar同时从-O2所述组件输出显示一

call    t_deriv_1::f() const
Run Code Online (Sandbox Code Playgroud)

在汇编中bar因为make_bar已知bar编译时被检查发现实际返回的类型总是如此t_deriv_1.

struct t_base
{
  virtual int f() const = 0;
  virtual ~t_base() {}
};
struct t_deriv_1 : t_base
{
  int f() const override final;
};
struct t_deriv_2 : t_base
{
  int f() const override final;
};

t_base * make_foo();
t_base * make_bar()
{
  return new t_deriv_1;
}

void foo()
{
  t_base * p = make_foo();
  p->f();
  delete p;
}

void bar()
{
  t_base * p = make_bar();
  p->f();
  delete p;
}
Run Code Online (Sandbox Code Playgroud)