寻求有关 C++ 静态成员初始化的清晰度

Seeking clarity regards C++ static member initialization

提问人:skpro19 提问时间:7/6/2023 更新时间:7/6/2023 访问量:60

问:

我对 C++ 类/结构静态成员的初始化和使用感到非常困惑。

假设我在名为 的头文件中定义了一个结构。这是它的样子——MapMetaDataConstants.h

struct MapMetaData {
            
            
            static float cell_size_, origin_x_, origin_y_;
            static unsigned int height_, width_;
            
            

        };

现在,假设我在某个源文件中使用它。struct

我不明白为什么我不能直接做

MapMetaData::cell_size_ = my_value

而不是

float MapMetaData::cell_size = 0.0; // intializing the static member MapMetaData::cell_size_ = my_value?然后给它赋值

  • 为什么需要显式初始化静态成员?
  • 初始化时,为什么需要指定“float”说明符?
  • 为什么需要全局初始化?为什么我不能在某个函数的范围内启动它,然后在另一个函数中使用它,因为它毕竟是一个静态成员?

尝试在不初始化的情况下直接调用,我得到MapMetaData::cell_size_ = my_value

undefined reference to MapMetaData::origin_x_ 

错误。

C++ 构造函数 初始化 static-members

评论

1赞 Some programmer dude 7/6/2023
您在结构中所做的是声明变量。然后,您需要定义它们。但是,在定义变量时,无需对变量进行显式初始化。定义 like 是完全可以的,并将值设置为 。如果要跳过单独的声明和定义,可以将成员标记为 .如float MapMetaData::cell_size_;0.0finlineinline static float cell_size_;
1赞 Some programmer dude 7/6/2023
另一方面,您几乎从不需要使用变量或值。请改用。floatdouble
7赞 john 7/6/2023
你混淆了声明定义初始化赋值。在你理解差异之前,任何事情都不会有意义。所以先理解概念,再担心语法,
0赞 john 7/6/2023
例如,初始化失败永远不会导致未定义的引用错误,但定义失败可能会导致错误。您可以在同一行代码中定义和初始化(尽管您不必这样做),但它们是不同的东西。
3赞 Some programmer dude 7/6/2023
另外,什么要求导致了在这里有成员变量的设计和实现?这些变量的目的是什么?他们应该解决什么原始问题?static

答:

2赞 nielsen 7/6/2023 #1

的声明告诉编译器将有一个静态变量。这为变量提供了一个名称,然后包含的模块可以引用该变量。Constants.hMapMetaData::cell_sizeConstants.h

稍后,通常会在 中定义变量:Constants.cpp

float MapMetaData::cell_size = 0.0f;  // Explicit initialization

它告诉编译器在程序中分配一块内存来存储变量。初始化 () 告诉编译器在程序启动时将哪个值放入该内存中。静态变量始终是初始化的。如果未提供任何值,即:... = 0.0f;

float MapMetaData::cell_size;  // Implicit initialization

然后将变量初始化为“0”(非静态变量不一定如此)。

如果省略变量定义,则不会创建变量的存储,因此链接器无法创建程序,因为它无法解析对变量的引用。因此,会给出一条错误消息,就像您观察到的那样。

稍后,您可以为变量值:

MapMetaData::cell_size = my_value;

这告诉编译器创建代码,将 的内容复制到 。my_valueMapMetaData::cell_size

因此,这些代码行不是多余的。每个都有特定的功能。

评论

1赞 MSalters 7/6/2023
“这些语句” - 只有赋值是语句。声明(包括定义)不是声明。这就是声明可以在函数外部发生的原因。
0赞 nielsen 7/6/2023
@MSalters 当然,你是对的。更改为“这些代码行”。谢谢。