C++ 无法重写派生类中的静态初始化

C++ 无法重写派生类中的静态初始化,c++,inheritance,static-initialization,C++,Inheritance,Static Initialization,我试图为层次结构中的类提供不同的静态初始化,但当我尝试使用以下代码时: #include <iostream> using namespace std; struct base { static const char* componentName; }; const char* base::componentName = "base"; struct derived : public base {}; const char* derived::componentName =

我试图为层次结构中的类提供不同的静态初始化,但当我尝试使用以下代码时:

#include <iostream>

using namespace std;

struct base {
static const char* componentName;
};
const char* base::componentName = "base";

struct derived : public base {};

const char* derived::componentName = "derived";

int main() {

cout << base::componentName << endl;
cout << derived::componentName << endl;
}

似乎无法在派生类上重写静态初始化?如果这不起作用,我可能总是将componentName定义为一个返回常量char*的静态函数,唯一的问题是我希望对部分专门化进行初始化,而我所知道的似乎没有任何方法可以在部分专门化中只重定义一个函数,如果不复制所有其他基本保持不变的代码,您也需要在子类中声明它

struct derived : public base {
    static const char* componentName;
};

“重写”和“继承”是仅对对象有意义的术语。类变量不参与对象继承。

静态成员变量意味着该类的所有实例都共享一个变量。尝试为基类指定一个值,为派生类指定另一个值是行不通的,因为它们都共享同一个变量,而这(显然足够)不能同时设置为两个不同的值

$9.4.2/2-“在以下定义中: 命名空间范围,名称空间的名称 静态数据成员应是合格的 通过类名,使用:: 接线员。”

而且

似乎静态初始化 无法在派生服务器上重写 上课

请记住,重写仅适用于虚拟函数

$10.3/2-“如果是虚拟会员 函数vf在类中声明 基类和派生类中的 直接或间接地从基地,一个 具有相同名称的成员函数vf 和Base::vf相同的参数列表是 声明,然后派生::vf也是 虚拟的(无论是否如此) 声明)并覆盖97) Base::vf

您可以尝试像这样重新运行组件名称,同时获得使用多态代码的优势

struct base{
   virtual char const* myname(){
      return "base";
   }
   virtual ~base(){}
};

struct derived : base{
   virtual char const* myname(){
      return "derived";
   }
};

int main(){}

我认为原因确实是因为以下事实:

&base::componentName==&derived::componentName


它们引用同一个对象,并在
中初始化一个对象两次 “谁笑到最后,谁笑得最好”的态度不是一件好事

干杯


Vintz

如果在派生类中声明之前尝试初始化派生类中的静态变量,则会出现重新定义错误,因为派生类类似于基类,并且静态变量只为类定义一次,所以第二次初始化会导致重新定义错误

做你想做的事情的正确方法之一是:

struct a {
    virtual const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string a::ClassName = "StructA";

struct c : public a {
    const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string c::ClassName = "StructC";

a* a1 = new c();
cout << a1->getClassType() << endl;
结构a{ 虚拟常量字符串&getClassType()常量{ 返回类名; } 静态字符串类名称; }; 字符串a::ClassName=“StructA”; 结构c:公共a{ 常量字符串&getClassType()常量{ 返回类名; } 静态字符串类名称; }; 字符串c::ClassName=“StructC”; a*a1=新的c();
cout getClassType()这可能无法按照OP的要求工作。它将在派生类中创建一个单独的成员,该成员将隐藏基类中的成员。如果通过指向base的指针类型的指针访问派生类对象,您将获得基类值-可能不是所需的值。不确定目的是什么,但代码显式引用了
base::componentName
derived::componentName
-该特定实例可以工作。但是,任何关于通过指针动态获取组件名的幻想都不适用于这种方法。我只是想澄清一下,您的方法创建了两个独立的变量,而不是一个具有不同初始化值的变量;类::组件名。在virtuals内部使用该方法可能是另一种方法,但是,在这种情况下,我会执行类似于virtual const char*getComponentName(){return“derived”}的操作,在该类的所有实例中共享静态成员值;同意。但是“派生”与“基”不是同一个类,它应该继承成员和方法定义,在本例中,我们看到的是值也被继承的情况。这不是我所期望的,即使它是“标准的”@lurscher:no,派生的与base不是同一个类——但是派生的实例也是base的实例,所以它需要包括base的所有部分,包括成员变量。
struct a {
    virtual const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string a::ClassName = "StructA";

struct c : public a {
    const string& getClassType() const {
        return ClassName;
    }
    static string ClassName;
};
string c::ClassName = "StructC";

a* a1 = new c();
cout << a1->getClassType() << endl;