VC++ 警告 C4356:无法通过派生类初始化静态数据成员

VC++ Warning C4356: static data member cannot be initialized via derived class

本文关键字:派生 初始化 静态 数据成员 C4356 警告 VC++      更新时间:2023-10-16

以下代码发出此警告,但它似乎工作正常,因为 A::st 和 B::st 都已初始化并且实际上表示相同的字符串。在我的理解中,这是格式错误的代码,它不应该编译(我检查了 clang)。我想知道为什么VC ++不发出错误而不是警告?

#include <string>
#include <iostream>
class A
{
public:
    static const std::string st;
};
class B : public A
{
};
const std::string B::st = "abcd"; //warning C4356: 'A::st': static data member cannot be initialized via derived class
int main()
{
    std::cout << A::st << std::endl; // outputs "abcd"
    std::cout << B::st << std::endl; // outputs "abcd"
}

从继承定义一切都很好因为 B 是 A 加上一些额外的东西,但想想你定义的东西!您在类 a 中定义了一个静态常量字符串。因为它是静态的,所以它是全局的,对于 A 和 B 的所有实例都是相同的。因此,即使是 A 的直接实例也会用"abcd"初始化如果你有一个 D 也派生自 A 而不是来自 B,它将包含 abcd因为它是静态的,所以你无法定义一个包含"abcd"的B和一个包含一个包含"efgh"的D。我没有尝试过,但我很确定你会遇到一些麻烦如果您定义

clase D :public A
{
};
const std:string d:st = "efgh";

即使编译器只发出警告,它也取决于链接顺序,A::st 的内容是什么。它可能是"abcd"或"efgh",但d::st将是"abcd"或B::st将是"efgh",您无法为B定义"abcd",为D定义"efgh",因为它是静态的。