无法覆盖派生类中的静态初始化

发布于 2024-10-04 09:29:37 字数 865 浏览 8 评论 0原文

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

#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;
}

我最终遇到了此构建错误:

test.cpp:15: error: ISO C++ does not permit ‘base::componentName’ to be defined as ‘derived::componentName’
test.cpp:15: error: redefinition of ‘const char* base::componentName’
test.cpp:11: error: ‘const char* base::componentName’ previously defined here

看来静态初始化不能在派生类上重写?如果这不起作用,我可能总是将 componentName 定义为返回 const char* 的静态函数,唯一的问题是我希望对部分专业化进行初始化,并且似乎没有任何方法可以我知道在部分专业化中仅重新定义一个函数,而无需复制大部分保持不变的所有其他代码

i'm trying to provide different static initializations for classes in a hierarchy, but when i tried with this code:

#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;
}

I ended up with this build error:

test.cpp:15: error: ISO C++ does not permit ‘base::componentName’ to be defined as ‘derived::componentName’
test.cpp:15: error: redefinition of ‘const char* base::componentName’
test.cpp:11: error: ‘const char* base::componentName’ previously defined here

It seems that static initializations cannot be overriden on the derived classes? If this does not work i might always define the componentName to be a static function that returns a const char*, the only problem with that i was sort of hoping to do initializations for partial specializations, and there does not seem to be any way that i know of to redefine just a single function in a partial specialization, without copying all the other code that will remain mostly the same

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夜光 2024-10-11 09:29:37

您也需要在子类中声明它。

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

You need to declare it in your subclass too.

struct derived : public base {
    static const char* componentName;
};
第七度阳光i 2024-10-11 09:29:37

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

A static member variable means there is a single variable that's shared across all instances of that class. Trying to have one value for the base class and a different value for the derived class doesn't work because they're both sharing the same variable, which (obviously enough) can't simultaneously be set to two different values.

笑忘罢 2024-10-11 09:29:37

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

&base::componentName == &衍生::componentName

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

干杯。

文茨

I think the reason is really because the following is true:

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

they refer to the same object, and initializing an object twice in a
"who laughs last, laughs the best" manner cannot be a good thing.

Cheers.

Vintz

诠释孤独 2024-10-11 09:29:37

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

'overridding' and 'inheritance' are terms that make sense only with objects. Class variables do not participate in object inheritance.

自在安然 2024-10-11 09:29:37

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

并且...

看来是静态初始化
不能在派生上重写
课程?

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

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

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

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

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

int main(){}

$9.4.2/2 - "In the definition at
namespace scope, the name of the
static data member shall be qualified
by its class name using the ::
operator."

And...

It seems that static initializations
cannot be overriden on the derived
classes?

Please remember that overriding is only for virtual functions.

$10.3/2 - 'If a virtual member
function vf is declared in a class
Base and in a class Derived, derived
directly or indirectly from Base, a
member function vf with the same name
and same parameter list as Base::vf is
declared, then Derived::vf is also
virtual (whether or not it is so
declared) and it overrides97)
Base::vf.

You may try to retrun the component name like so while gaining advantage of working with polymorphic code.

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

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

int main(){}
狼性发作 2024-10-11 09:29:37

如果您尝试在派生类中声明之前在派生类中初始化静态变量,您将收到重新定义错误,因为派生类类似于基类,并且静态变量只为类定义一次,因此第二次初始化会导致重新定义错误。

执行您的意图的正确方法之一如下:

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;

注意
在上面的代码中,getClassType是虚函数,以字符串格式返回类类型。
该函数使用静态变量,也必须在派生类中重写。如果忘记重写它,编译器将调用该函数的基类版本,并且它将使用基类静态变量而不是派生类静态变量。所以,它会返回
基类的对象类型。

if you try to initialize the static variable in the derived class before declaring in your derived class you will get redefinition error because derived class is-like base class and static variables are only defined once for class so second initialization causes redefinition error.

One of the correct way to do what you are intending is below;

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;

NOTE
In the above code, getClassType is virtual function and returns class type in string format.
This function uses static variable and must be overridden in the derived class too. If you forget to override it, compiler will call base class version of the function and it will use the base class static variable instead of derived class static variable. So, it will returns
the object type of base class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文