类成员定义

Definition of class member

本文关键字:定义 成员      更新时间:2023-10-16

可以这样声明一个类成员:

class Test {
public:
    int a;
}

这是我们如何声明的,但是我想知道变量a在哪里定义。

我知道静态类成员,它是静态变量,所以它不能在类中定义,它应该在类外定义。所以我认为普通的类成员应该有一个定义的地方,我猜是在构造函数中隐式定义普通成员。对吗?

对于非静态数据成员,声明和定义是相同的。

所以我认为普通类成员应该有一个定义的地方,我猜是在构造函数中隐式定义普通成员。

我想我明白你的意思了。对于每个静态数据成员,每个类型只有一个变量实例(对于模板——每个模板实例化创建一个不同的类型)——这就是为什么声明更像是普通变量的外部声明——它说"这个变量将在某个地方有一个地址——稍后让链接器将地址缝合进去"。定义是程序要求编译器为特定翻译单元对象中的变量保留实际内存的地方,这些内存将被链接器找到,并使其他翻译单元中的代码可以根据声明访问该变量。(对于模板来说有点复杂)。因此,从程序员的角度来看,静态数据成员定义似乎是触发内存分配和安排构造函数运行的源代码行。一旦你写好了定义,分配和构造就都排序了。

对于非静态数据成员,这是完全不同的-当类定义被编译器解析时,仍然没有实际的请求为这些非静态数据成员提供任何内存,因为还没有该类类型的实例对象。只有当其他代码表明需要对象实例时,编译器才需要安排内存(如果不使用放置new)和构造。换句话说,对于非静态数据成员,定义和分配/构造通常是解耦的——使用单独的源代码。

这些都递归地应用:当对象实例本身是静态的或属于文件/命名空间范围时,内存和构造(包括类中的数据成员)将在看到定义时安排(不一定执行),如上所述。但对象实例通常位于堆栈或堆上。无论哪种方式,数据成员的分配和构造代码都是由包含对象的创建方式驱动的,与数据成员的定义无关。

对象的每个实例都在内存中为该对象预留了一些空间。可能在堆存储或堆栈上。

对象的每个成员变量都存储在该空间的特定位置。

a可以在声明之后定义,也可以在构造函数中定义,或者完全在类之外定义。下面是一个示例,展示了可以定义a的所有方法

class Test {
public:
    int a = 5;
    Test() {
        a = 5;
    }
};
int main() {
    Test foo;
    foo.a = 5;
    return 0;
}

作为一种良好的实践,您应该封装您的数据成员并在特定的方法中管理它们的定义,例如SetA()、GetA(),并且您可以在构造函数

中给出默认值