【问题标题】:Initialize the protected static member from the subclass从子类初始化受保护的静态成员
【发布时间】:2015-06-30 05:46:54
【问题描述】:

我想知道是否可以从子类初始化受保护的静态成员。
例如,

// head file
class Test
{
protected:
    static int i;
};
class Test2 : public Test{};

//cpp file
#include "headfile.h"
int Test2::i = 1;

如您所见,当我初始化这个静态成员 (i) 时,我使用了子类名称 (Test2)。
令我惊讶的是,我用 Visual Studio 2013 测试了这段代码,它没有出错。但是如果我在 Linux 下用 Netbeans(gcc11) 试了一下,我得到一个提示错误:
unable to resolve the identifier i
然后我编译了一下,报错信息是:
error: ISO C++ does not permit ‘Test::i’ to be defined as ‘Test2::i’ [-fpermissive]

现在,如果我在 Test 类中将 static int i 的 protected 更改为 public,错误就会消失。

我很困惑...这是我第一次发现 gcc 和 vs. 两个不同的结果。

【问题讨论】:

  • 你是如何在 Visual Studio 中测试它的?测试/代码与您在 netbeans 中所做的相同吗?鉴于您正试图公开访问私有变量,我认为这会出错。
  • @MarshallTigerus 我确信它们是完全相同的代码,因为我复制了它。事实上,我尝试了私有和受保护,它们都没有工作。只有公共工作。
  • i的访问权限改为public后Clang还是不接受。

标签: c++ static initialization


【解决方案1】:

该定义违反了 C++14 [class.static.data] §9.4.2/2。强调我的:

在命名空间范围的定义中,静态数据的名称 成员应使用::其类名限定 运算符。

较新版本的 GCC(在 Coliru 上)的行为与限定符无关。您可以使用-fpermissive 消除 GCC 上的错误,但请注意,您仍然只定义了一个属于基类的对象。

【讨论】:

  • @Thomas 我引用了该标准的最新版本,但该规则根本不是新的。完全相同的单词在 C++98 中具有相同节号的完全相同的段落中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 2011-09-27
  • 2014-01-30
  • 2015-05-18
  • 2023-03-18
  • 1970-01-01
  • 2011-01-18
相关资源
最近更新 更多