【问题标题】:C++ error: base function is protectedC++ 错误:基函数受保护
【发布时间】:2013-06-06 19:56:03
【问题描述】:

我想知道为什么下面的代码不能编译:

class base {
protected:
  typedef void (base::*function_type)() const;
  void function_impl() const {} // error: ‘void base::function_impl() const’ is protected
};

class derived: public base {
public:
  operator function_type() const {
    return boolean_test() == true ? &base::function_impl : 0; // error: within this context
  }

protected:
  virtual bool boolean_test() const = 0;
  virtual ~derived() {}
};

int main(int argc, char* argv[]) {
}

g++ 输出:

~/protected_test$ g++ src/protected_test.cpp
src/protected_test.cpp: In member function ‘derived::operator base::function_type() const’:
src/protected_test.cpp:4:8: error: ‘void base::function_impl() const’ is protected
src/protected_test.cpp:10:44: error: within this context

这段代码改编自here,我在论坛上看到没有人抱怨这一点。另外,我使用的是 g++ 4.7.2,并且相同的代码可以与 egcs-2.91.66 进行编译和链接。

【问题讨论】:

  • 要么一个编译器有问题,要么另一个。 :D

标签: c++ g++


【解决方案1】:

受保护访问的规范规定,指向成员的指针必须通过派生类型(即derived::...)或从其继承的类型来形成。您不能直接通过base 命名function_impl

这意味着在你的情况下你必须这样做

operator function_type() const {
  return boolean_test() == true ? &derived::function_impl : 0;
}

注意,即使你使用&derived::function_impl表达式获取地址,结果的类型仍然是void (base::*function_type)() const,因为在这种情况下名称function_impl解析为base类的函数。

如果它曾经在某个特定的编译器(或它的某个特定版本)中编译,则仅表示该编译器允许错误漏掉,这可能是链接中代码的原因。

【讨论】:

  • 我不同意结果的类型——你描述的行为不是类型安全的(我不确定是你的错误还是 C++ 标准的错误)。这造成了一个漏洞,允许Derived 成员函数间接调用o.function_impl(),即使dynamic_cast<Derived&>(o) 不应该是合法的。
  • 好的,C++ 标准中的例子好像坏了。
  • @Ben Voigt:请您详细说明一下吗?
  • 比较 ideone.com/pEXk9Wideone.com/zJX5U6 绝对是标准被打破,而不是你在这个答案中的解释。
猜你喜欢
  • 2016-03-26
  • 2014-11-03
  • 2011-05-27
  • 2011-02-02
  • 2017-08-05
  • 2011-05-30
  • 2014-08-29
  • 1970-01-01
  • 2017-05-15
相关资源
最近更新 更多