C++类静态成员的初始化

记住:通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化!!!

#include<iostream>
usingnamespacestd;
classtest
{
public:
staticint num;
};
inttest::num = 0;
void main()
{
cout<<test::num <<endl;
test::num = 20;
cout<<test::num <<endl;
}

一般地静态数据成员在该类定义之外被初始化如同一个成员函数被定义在类定义之
外一样,在这种定义中的静态成员的名字必须被其类名限定修饰,如上例中的
inttest::num = 0;
与全局对象一样对于静态数据成员在程序中也只能提供一个定义,这意味着静态数据成员的初始化不应该被放在头文件中而应该放在含有类的非inline函数定义的文件中, 静态数据成员可以被声明为任意类型它们可以是const 对象数组或类对象等等

#include<string>
class Account {
// ...

private:
staticconststring name;
};
conststring Account::name("Savings Account");

作为特例有序型的const 静态数据成员可以在类体中用一常量值初始化, 例如如果决定用一个字符数组而不是string 来存储账户的姓名那么我们可以用int型的const数据成员指定该数组的长度例如:

// 头文件
class Account {
// ...
private:
staticconstint nameSize = 16;//好像vc下不支持这样
staticconstchar name[nameSize];
};
// 文本文件
constint Account::nameSize;// 必需的成员定义

constchar Account::name[nameSize]="Savings Account";

于这个特例有一些有趣的事情值得注意, 用常量值作初始化的有序类型的const 静态数据成员是一个常量表达式constant expression ,如果需要在类体中使用这个被命名的值那么类设计者可声明这样的静态数据成员, 例如因为const 静态数据成员nameSize是一个常量表达式所以类的设计者可以用它来指定数组数据成员name 的长度, 在类体内初始化一个const 静态数据成员时该成员必须仍然要被定义在类定义之外
但是因为这个静态数据成员的初始值是在类体中指定的, 所以在类定义之外的定义不能指定初始值, 因为name 是一个数组不是有序类型所以它不能在类体内被初始化, 任何试图这么做的行为都会导致编译时刻错误例如:

class Account {
// ...
private:
staticconstint nameSize = 16;// ok: 有序类型
staticconstchar name[nameSize]= "Savings Account";// 错误
};

name 必须在类定义之外被初始化, 这个例子还说明了一点, 我们注意到成员nameSize指定了数组name 的长度, 而数组name的定义出现在类定义之外,
const char Account::name[nameSize] = "Savings Account";

nameSize 没有被类名Account 限定修饰. 尽管nameSize是私有成员, 但是name的定义仍没有错, 怎么会这样? 如同类成员函数的定义可以引用类的私有成员一样静态数据成员的定义也可以引用静态数据成员, name 的定义是在它的类的域内当限定修饰名Account::name被看到之后它就可以引用Account 的私有数据成员


转自:http://blog.sina.com.cn/s/blog_6f6769b50100mub3.html

<think>好的,我现在需要回答用户关于C++静态成员初始化的问题。首先,我得回忆一下静态成员的基本概念。静态成员属于本身,而不是的实例,所以它们的初始化方式应该和普通成员不同。 用户可能想知道如何在C++中正确初始化静态成员变量。我记得静态成员变量需要在外部进行定义和初始化,但具体语法可能容易混淆。比如,静态成员内声明,然后在外使用作用域解析运算符来定义。比如,内声明static int count;,然后在外定义int MyClass::count = 0;。 不过,如果是const静态成员,情况可能不同。C++11之后,允许在内直接初始化const静态整型成员,比如static const int a = 10;。但非整型的const静态成员可能还是需要在外定义,即使有初始化。比如,static const double pi = 3.1415;可能还需要在外定义,否则如果取地址会导致链接错误。 另外,内联静态成员C++17引入)允许在内直接初始化,无需外定义。比如inline static int x = 5;。这点可能需要提到,特别是用户如果使用的是较新的标准。 可能还需要提到静态成员函数,它们只能访问静态成员变量,不能访问非静态成员。不过用户的问题集中在初始化,所以这部分可以简要带过。 需要分点说明不同的情况:普通静态成员、const静态整型、const静态非整型、内联静态成员。每个情况给出例子,说明正确的初始化方式。同时,提醒常见的错误,比如忘记外定义导致链接错误,或者在初始化非const静态成员等。 总结步骤:先声明静态成员内,然后在外定义和初始化(除特殊情况如内联或const整型)。强调静态成员的存储空间由所有实例共享,生命周期是整个程序运行期间。 可能还需要解释为什么静态成员需要这样的初始化方式,因为它们在所有实例之间共享,必须在程序开始时分配内存,而不是在实例创建时。因此,外定义实际上是分配存储空间的过程。 最后,检查是否有遗漏的情况,比如模板中的静态成员初始化是否不同,但可能用户的问题不涉及模板,所以暂时不提。保持回答简洁明了,覆盖主要情况即可。</think>在C++中,静态成员初始化需要遵循特定规则,以下是具体实现方式: $$ \textcolor{blue}{// 示例声明} $$ ```cpp class MyClass { public: static int count; // 普通静态成员声明 static const int MAX = 100; // const整型静态成员C++11起可直接初始化) static constexpr double PI = 3.14159; // constexpr静态成员C++11) inline static std::string name = "Test"; // 内联静态成员C++17) }; ``` 具体分为三种情况: 1. **普通静态成员** - 内声明,初始化(必须使用作用域运算符) ```cpp int MyClass::count = 0; // 正确初始化方式 ``` 2. **const静态成员** - 整型(int, char, bool等)可在内直接初始化: ```cpp static const int MAX = 100; // 合法 ``` - 非整型需在外定义(C++11起可用constexpr): ```cpp constexpr double MyClass::PI; // C++11及以上 ``` 3. **内联静态成员C++17)** - 可直接在初始化: ```cpp inline static std::string name = "Test"; ``` $$ \textcolor{red}{错误示例} $$ ```cpp class ErrorExample { public: static int value = 10; // 错误!非const/inline静态成员不能在初始化 }; ``` 关键特性: 1. 静态成员独立于实例存在(生命周期=程序周期) 2. 静态成员函数只能访问静态成员变量 3. 所有实例共享同一静态成员存储空间 建议:优先使用C++17的`inline static`进行初始化,既保证可读性又避免忘记外定义导致的链接错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值