明确解决类成员的范围

101*_*010 3 c++ language-lawyer c++11 c++14

请考虑以下示例:

#include <iostream>

struct foo {
    void fun() const { std::cout << "foo::fun()" << std::endl; }
};

auto main() -> int {
  foo f;
  f.fun();
  f.foo::fun();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

DEMO

  • 如上例所示,成员函数foo::fun()以两种不同的方式引发.

  • 在第二个调用(即,f.foo::fun())中,成员类的范围foo::fun()被明确消除歧义/已解决.

问题:

  1. 这两个电话之间有什么区别(即,f.fun()f.foo::fun())?
  2. 调用成员函数或可公开访问的成员变量是否有任何优势,通过明确消除其范围与经典方式调用它的范围?
  3. 通过明确消除其范围歧义,调用成员函数或可公开访问的成员变量是否存在任何缺陷?

Pra*_*ian 9

一个区别是,如果fun()是一个virtual函数,第二种方式调用它会抑制虚拟调度.

struct foo {
    void virtual fun() const { std::cout << "foo::fun()" << std::endl; }
};
struct bar : foo {
    void fun() const override { std::cout << "bar::fun()" << std::endl; }
};

auto main() -> int {
  bar b;
  foo *f = &b;
  f->fun();
  f->foo::fun();
}
Run Code Online (Sandbox Code Playgroud)

输出:

bar::fun()
foo::fun()
Run Code Online (Sandbox Code Playgroud)

现场演示


同样,如果您反而从基类隐藏了一个函数,它允许您访问基类版本.

struct foo {
    void fun() const { std::cout << "foo::fun()" << std::endl; }
};
struct bar : foo {
    void fun(int) const { std::cout << "bar::fun()" << std::endl; }
};

auto main() -> int {
  bar b;
  b.fun(10);
  b.foo::fun();
}
Run Code Online (Sandbox Code Playgroud)