【C/C++】类中的static成员、static const成员和const成员

const 数据成员


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

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




static 数据成员


static 数据成员目的是作为类作用域的全局变量,被类里的所有对象共享,即使没有创建任何对象,该成员也存在。static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象。在类的内部只是声明,定义必须在类定义体的外部,并且不能在函数体内,通常在类外定义时初始化,或者使用静态函数初始化。借用 gcc 的话:ISO C++ forbids in-class initialization of non-const static member

注意:static 成员变量的内存空间既不是在声明类时分配,也不是在创建对象时分配,而是在编译时在静态数据区分配内存,到程序结束时才释放。



const static 数据成员


const static 数据成员被一个类的所有对象共享,常量,可以在类内定义处初始化,也可以在类外初始化。




const 成员函数


const 成员函数主要是防止修改对象的成员变量(mutable 修饰的成员变量,static 变量除外)。即const成员函数不能修改成员变量的值,但可以访问成员变量。注意 const 成员函数只能保证不修改当前 this 指针所指的对象的成员变量,若通过参数传递进来有别的对象名,是可以修改其成员变量的,还有就是在 const 成员函数里通过 const_cast 移除 *this 的 const 特性后调用一些非 const 成员函数也有可能会改变 *this 对象的成员变量,虽然这种做法其实是错误的。




static 成员函数


static成员函数主要目的是作为类作用域的全局函数,不能访问类的非静态数据成员。类的静态成员函数没有this指针,这导致:

1、静态成员函数可以直接访问类的静态数据和函数成员,而访问非静态成员必须通过参数传递的方式得到一个对象名,然后通过对象名来访问,与其不同的是非静态成员函数可以任意地(非)静态成员函数和(非)静态数据成员;

2、不能被声明为virtual。


注意: 与数据成员不同,static 与 const 不能同时修饰成员函数

原因:const 修饰符用于表示函数不能修改成员变量的值,该函数必须是含有 this指针 的类成员函数,函数调用方式为 __thiscall ,而 static 函数是不含有 this指针 的,调用规约是 __cdecl 或 __stdcall ,两者是冲突的。


下面来一个完整的例子:

#include <iostream>

using namespace std;
class boy
{
	public:
		boy(int _a):a(_a){}                  //常量初始化
		static int Init();                   //静态成员函数声明,只能访问静态数据成员
		void display() const;                //const成员函数声明
		void test();
		static void say();

		const int a;                         //常量定义
		static int b;                        //静态变量声明
		const static int c = 3;              //类内定义+初始化静态常量,与 static const int c = 3 一个意思
};

int boy::b = boy::Init();                            //静态函数初始化静态变量
//int boy::b = 2;                                    //类外定义+初始化静态变量,不用加 static, public, pirvate 等修饰
//const int boy::c = 3;                              //类外定义+初始化静态常量,不用加 static, public, private 等修饰

int boy::Init()
{
	return c;
}

void boy::display() const                             //关键字 const 必须用同样的方式重复出现在函数定义处
{
	cout << a << " " << b << " " << c << endl;
}

void boy::test()                                      //非静态成员函数,可直接访问(非)静态数据成员与(非)静态成员函数
{
	cout << a << " " << b << " " << c << endl;
	display();
	say();
}

void boy::say()                                       //静态成员函数,可直接访问静态数据成员与静态成员函数
{
	cout << b << " " << c << endl;
}

int main()
{
	boy b(1);
	boy d(2);
	cout << b.a << " " << b.b << " " << b.c << endl; //通过对象访问静态数据成员,同理也可通过对象访问静态成员函数
	cout << boy::b << " " << boy::c << endl;         //通过类访问静态数据成员
	b.display();   
	cout << &b.b << " " << &d.b << " " << &boy::b << endl;  //静态数据成员共享同一内存
	b.test();                    
	return 0;
}



  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
静态数据成员和静态成员函数的用法: 静态数据成员和静态成员函数一般用于实现与相关的全局函数,如工具函数、工厂函数等。静态数据成员和静态成员函数可以通过名和作用域解析运算符::来访问。使用静态数据成员和静态成员函数可以提高程序的效率,减小程序的内存开销。但需要注意,静态数据成员和静态成员函数都不能访问非静态成员,因此需要根据具体情况选择是否使用。 const修饰对象和成员的概念用法: constC++中的关键字,它用于修饰对象和成员const修饰的对象和成员不能被修改,从而保证了程序的安全性和稳定性。 const修饰对象:const修饰的对象不能被修改,它的值在初始化之后就不能被改变。例如:const int a = 10;表示a是一个常量,它的值不能被修改。 const修饰成员const修饰的成员不能被修改,它在类中一般用于声明常量成员或常量成员函数。例如:const int MAX_SIZE = 100;表示MAX_SIZE是一个常量,它的值不能被修改。又例如:void print() const;表示print()函数是一个常量成员函数,它不能修改成员变量,只能读取成员变量的值。 使用const修饰对象和成员可以提高程序的安全性和可读性,减少程序的错误。但需要注意,const修饰的对象和成员在初始化后不能被修改,因此需要根据具体情况选择是否使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值