明确解决类成员的范围

时间:2014-06-18 21:41:49

标签: c++ c++11 language-lawyer 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;
}

DEMO

  • 如上例所示,成员函数foo::fun()有两种不同的方式。

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

问题:

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

2 个答案:

答案 0 :(得分: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();
}

输出:

bar::fun()
foo::fun()

Live demo


同样,如果你是从基类隐藏一个函数,它允许你访问基类版本。

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

答案 1 :(得分:2)

在您的示例中,调用语法没有任何语义差异。

但请考虑以下示例

#include <iostream>

struct A
{
   void f() { std::cout << "A::f()" << std::endl; }
};

struct B : A
{
   void f() { std::cout << "B::f()" << std::endl; }
};

int main()
{
   B b;

   b.f();
   b.A::f();
}

或者考虑一个更有趣的例子,虽然它没有任何重要意义,但从范围解析的角度来看它很有趣。

#include <iostream>

struct A
{
    virtual ~A() { std::cout << "A::~A()" << std::endl; };
};

struct B : A
{
     ~B() { std::cout << "B::~B()" << std::endl; };
};


int main() 
{
    B b1;

    b1.~A();

    std::cout << "End of the first part\n\n";

    B b2;

    b2.A::~A();

    std::cout << "End of the second part\n\n" << std::endl;

    return 0;
}

输出

B::~B()
A::~A()
End of the first part

A::~A()
End of the second part


B::~B()
A::~A()
B::~B()
A::~A()

考虑到我故意使用名为~A

的析构函数