如何初始化const和static数据成员

本文详细解析了C++中static和const的使用方法及其特性,包括static数据成员、const成员变量及成员函数的定义与初始化过程。同时介绍了const成员函数的特点及如何在构造函数初始化列表中设置const成员变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通常在类外初始化static数据成员,但是 static const 的整型(bool,char,int,long)可以再类声明中初始化,static const的其他类型也必须在类外初始化(包括整型的数组)。

const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间。 

static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。

在C++中,static静态成员变量不能在类的内部初始化。在类的内部只是声明,定义必须在类定义体的外部,通常在类的实现文件中初始化,如:double Account::Rate = 2.25;static关键字只能用于类定义体内部的声明中,定义时不能标示为static

在C++中,const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数

const数据成员 只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类的声明中初始化const数据成员,因为类的对象没被创建时,编译器不知道const数据成员的值是什么。

const数据成员的初始化只能在类的构造函数的初始化列表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static cosnt。

 

const成员变量

#include <iostream>
using namespace std;

class A
{
    public:
        A(int size) : SIZE(size) {};
    private:
        const int SIZE;
};

int main()
{
    A a(100);
}

说明

  • 在类中声明变量为const类型,但是不可以初始化
  • const常量的初始化必须在构造函数初始化列表中初始化,而不可以在构造函数函数体内初始化
  • #include <iostream>
    using namespace std;
    
    class A
    {
        private:
            enum {SIZE = 100};
        public:
            int array[SIZE];
    };
    
    int main()
    {
        A a;
    }

    枚举常量不会占据对象的存储空间,在编译时被全部求值

    但是,它隐含的数据对象类型为整形,不能表示其他类型。

话说有几个地方必须在构造函数的初始化列表中(初始化列表里初始化):

  1. 类的const常量
  2. 类的引用类型成员
  3. 没有默认构造函数的类类型成员
  4. 如果类存在继承关系,派生类必须在其初始化列表中调用基类的构造函数

 

const成员函数(详见

类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。

#include <iostream>
using namespace std;
class Stack
{
    public:
        void Push(int item);
        int Pop(void);
        int GetCount(void) const;
    private:
        int m_num; 
        int m_data[100];
};

int Stack::GetCount(void) const
{
    ++m_num;     //编译错误,企图修改数据成员
    Pop();       //编译错误,企图调用非const函数
    return m_num;
}

同一个类中,可以仅通过是否是const定义两个函数名字、参数、返回值完全相同的两个成员函数,在调用时,const对象调用const成员函数,非const对象调用非const成员函数。

 

不可以在const函数中改变成员变量的值,那么有没有办法改变?

答案是可以的,把成员变量声明为mutable类型。

当类中只有const函数,非const对象是否可以调用const函数? 可以

但是当含有非const函数时,非const对象不可以调用那个同名const函数(否则,类的数据变量就会发生变化)。

当类中存在一个const和一个普通的两个同名函数时,const对象是否可以暂时调用那个非const函数?

答案是可以的。用const_cast将转化掉表达式的const性质

 

#include <iostream>
using namespace std;

class A
{
    public:
        A(int v): val(v) {}
        void print_val() { cout << "not const:" << val << endl;}
        void const print_val() const { cout << "const print_val:" << val << endl;}
    private:
        int val;
};
int main(int argc ,char **argv)
{
    A b(45);
    b.print_val();

    const A *a = new A(45);
    const_cast<A*>(a)->print_val();
    a->print_val();
}

 

<think>嗯,用户问的是如何初始化const数据。我得先回忆一下const在C++里的用法。首先,const变量是常量,定义后不能修改,所以初始化必须在定义的时候完成。那有哪些方法可以初始化呢? 可能需要分情况讨论。比如,普通的局部const变量,应该在声明时直接赋值,比如const int a = 5;对吧。然后,类的const成员变量,因为不能在声明时直接初始化,除非是静态的。所以这时候必须用构造函数的初始化列表来初始化。比如在构造函数后面加: b(value)这样的形式。 还有静态的const成员变量,这时候如果在类内初始化,可能需要C++11之后的特性,或者在类外定义。比如类内声明static const int c = 10;然后在类外定义一次,但如果是整型可能可以在声明时直接初始化。 另外,const的指针引用也需要初始化。比如指针的话,要指向某个地址,而引用必须绑定到一个对象。比如const int &d = a;或者const int *p = &a; 可能还有数组的情况,比如const数组初始化,可以在声明时用花括号列表初始化,比如const int arr[] = {1,2,3}; 然后用户可能需要示例代码来说明这些情况,这样更清楚。需要确保每个例子都符合语法,并且正确使用初始化方法。比如类的例子,要写出类中的const成员,然后在构造函数初始化列表里初始化。可能还要提到,如果没有初始化列表,会导致编译错误。 另外,用户可能对不同的作用域感兴趣,比如全局的const变量怎么初始化,可能在文件作用域直接赋值。或者在函数内的局部const变量。 还要注意,C++中const默认是内部链接,所以如果在头文件定义的话可能需要加inline或者static,或者在实现文件中定义。不过这可能超出用户当前的问题范围,但如果有必要可以简单提一下。 总结下来,应该分几种情况:基本类型、类成员、静态成员、指针引用、数组等。每种情况给出正确的初始化方法,并附上例子。确保用中文解释清楚,结构清晰,步骤明确。</think>初始化 `const` 数据(常量数据)需要根据其作用域类型选择不同的方式。以下是不同场景下的初始化方法: --- ### 一、基本类型(局部或全局作用域) **规则**:必须在定义时直接初始化。 **示例**: ```cpp const int a = 10; // 全局常量,定义时初始化 void func() { const double PI = 3.14; // 局部常量,定义时初始化 } ``` --- ### 二、类的 `const` 成员变量 **规则**:必须通过构造函数的**初始化列表**(Initializer List)初始化。 **示例**: ```cpp class MyClass { public: const int value; // 常量成员变量 MyClass(int x) : value(x) {} // 通过初始化列表赋值 }; ``` --- ### 三、类的 `static const` 成员变量 **规则**:需在类外单独定义(C++11 后允许类内初始化整型常量)。 **示例**: ```cpp class MyClass { public: static const int MAX = 100; // C++11允许类内初始化(仅限整型) }; // 类外定义(非整型必须如此) const int MyClass::MAX; // 若类内已初始化,此处可省略赋值 ``` --- ### 四、`const` 指针或引用 1. **常量指针**(指向不可变地址): ```cpp int x = 5; int* const ptr = &x; // ptr本身是常量,需初始化 ``` 2. **指向常量的指针**(值不可变): ```cpp const int* ptr = &x; // ptr指向的值不可变 ``` 3. **常量引用**: ```cpp const int& ref = x; // 引用必须初始化,且不可通过ref修改x ``` --- ### 五、数组的 `const` 初始化 **规则**:必须在定义时用初始化列表赋值。 **示例**: ```cpp const int arr[] = {1, 2, 3}; // 正确 ``` --- ### 六、注意事项 1. **禁止修改**:所有 `const` 数据初始化后不可再赋值。 2. **动态初始化**:若初始化依赖运行时计算,需通过函数返回值或表达式: ```cpp const int size = getSize(); // 假设getSize()返回int ``` --- ### 总结步骤 1. **确定作用域**:全局、局部或类成员。 2. **选择初始化方式**:直接赋值、构造函数初始化列表或静态定义。 3. **验证语法**:确保初始化操作在定义时完成。 通过以上方法,可以正确且安全地初始化 `const` 数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值