首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么需要定义C++静态数据成员,而不需要非静态数据成员?

为什么需要定义C++静态数据成员,而不需要非静态数据成员?
EN

Stack Overflow用户
提问于 2021-11-21 12:37:40
回答 3查看 334关注 0票数 1

我试图理解声明与静态和非静态数据成员的定义之间的区别。抱歉,如果我根本上错过了理解的概念。非常感谢你的解释。

试图理解的代码

代码语言:javascript
复制
class A
{
public:
    int ns; // declare non-static data member.
    static int s; // declare static data member. 
    void foo();
    
};
 
int A::s; // define non-static data member.
// int A::ns; //This gives an error if defined.

void A::foo()
{
    ns = 10;
    s = 5; // if s is not defined this gives an error 'undefined reference'
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-11-21 13:29:23

当您声明某一项时,您将告诉编译器声明的名称是存在的,它是什么样的名称(类型、变量、函数等)。定义可以与声明(如类A)一起使用,也可以位于其他地方--编译器和链接器必须在稍后将两者连接起来。

变量或函数定义的关键点是它告诉编译器和链接器这个变量/函数将存在于何处。如果您有一个变量,则需要在内存中为它提供一个位置。如果您有一个函数,则需要在包含函数指令的二进制文件中有一个位置。

对于非静态数据成员,声明也是定义。也就是说,你给了他们一个居住的地方。这个地方在类的每个实例中。每次生成一个新的A对象时,它都会附带一个ns作为其一部分。

另一方面,静态数据成员没有关联的对象。如果没有定义,就会有N个A实例共享相同的s,但是没有地方放置s。因此,C++使您通过定义为它选择一个翻译单元,最常见的是与该标头相对应的源文件。

您可能会认为编译器应该只为它选择一个实例,但由于各种原因,这是行不通的,原因之一是您可以在创建实例之前使用静态数据成员,或者在最后一个实例消失之后使用静态数据成员,或者根本没有实例。

现在你可能会想,为什么编译器和链接器仍然不能自己解决它,而且.实际上,如果您在变量或函数上使用inline,那么实际上会发生什么情况。您可以得到多个定义,但只会选择一个定义。

他说:给他们一个住的地方有点离题。编译器只需要知道当它创建该类的对象时,需要知道给它多少空间,以及该空间的哪个部分是哪个数据成员。您可以将其看作是为您执行定义部分的编译器,因为只有一个地方可以让数据成员居住。

票数 2
EN

Stack Overflow用户

发布于 2021-11-21 13:35:04

static成员本质上是全局变量,具有与类相关联的特殊名称和访问规则。因此,它们继承了通常全局变量的所有问题。也就是说,在整个C++程序(它是所有翻译单元的联合,也就是.cpp文件)中,每个全局变量都应该有一个定义,仅此而已。

您可以将“变量定义”看作“为变量分配内存的位置”。

但是,类通常定义在包含在多个翻译单元中的头文件(.h/.hpp/etc)中。因此,应该由程序员来指定哪个翻译单元真正定义了变量。注意,由于C++17,我们有inline关键字,它将这一负担分配给编译器,因此要查找“内联变量”。由于历史原因,命名方式很奇怪。

但是,在创建类的实例(即对象)之前,非static成员实际上并不存在。对象生存期和存储持续时间决定了每个成员是如何创建/存储/销毁的。因此,没有必要在类之外的任何地方实际定义它们。

票数 1
EN

Stack Overflow用户

发布于 2021-11-21 13:29:59

static变量属于类定义。non-static变量属于用类定义创建的实例。

代码语言:javascript
复制
int main()
{
    A::s = 5; // this is ok

    A a;
    a.ns = 5 // this is also ok
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70054587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档