初始化列表及const、static修饰成员

本文详细探讨了C++中构造函数的初始化列表的重要性,解释了成员变量初始化的顺序规则,常对象和常方法的使用限制,以及static修饰符在成员变量和方法中的作用。通过实例代码,阐述了这些特性如何影响程序的行为。

1、构造函数的初始化列表

初始化顺序和初始化列表的顺序无关,和成员变量/对象的声明顺序有关。

class Test
{
public:
	Test(int a, int b) : mb(ma), ma(a), mc(ma)
	{}
	void Show()
	{
		std::cout << "ma:" << ma << std::endl;
		std::cout << "mb:" << mb << std::endl;
		std::cout << "mc:" << mc << std::endl;
	}
private:
	int ma;
	int mb;
	int mc;
};
int main()
{
	Test test1(10,20);
	test1.Show();
	return 0;
}

运行结果为:ma =10;mb = 10;mc = 10; 

2、常对象和常方法

  1. 常对象不能调用普通方法
  2. 常对象只能调用常方法
  3. 普通对象也可以调用常方法
  4. 普通方法可以调用常方法
  5. 常方法中不能调用普通方法
class Test
{
public:
	Test(int a, int b) : mb(b), ma(a)        //this Test* const
	{}
	void Show()const                            //this  const Test* const
	{
		std::cout << "ma:" << ma << std::endl;
		std::cout << "mb:" << mb << std::endl;
	}
	void Print()                                     //this Test* const
	{
		std::cout << "hello world !" << std::endl;
		//(*this).Show();
	}
private:
	int ma;
	int mb;
};

int main()
{
	Test test1(10, 20);
	test1.Show();                        //Test*  ==> Test* const
	const Test test2(30, 40);
	test2.Show();                       //const Test*  ==>  Test* const
	system("pause");
	return 0;
}

常成员变量:一定要初始化(构造函数的初始化列表中)

class Test
{
public:
	Test(int a, int b) :       
		ma(a)
	{
		mb = b;
	}
	void Show()
	{
		std::cout << "ma:" << ma << std::endl;
		std::cout << "mb:" << mb << std::endl;
	}

private:
	const int ma;         //ma必须初始化
	int mb;
};
int main()
{
	Test test1(10, 20);
	test1.Show();
	system("pause");
	return 0;
}

3、static修饰词

修饰成员变量

  1. 不属于对象独享(对象共享)
  2. 一定要在类外初始化
  3. 不依赖对象访问

修饰成员方法

  1. _cdecl,没有this指针
  2. 不能访问普通成员变量
  3. 可以访问静态的成员变量和全局变量
  4. 静态成员方法不能调用普通的成员方法
  5. 普通成员方法可以调用静态的成员方法
int gdata = 10;
class Test
{
public:
	Test(int a, int b)
	{
		mb = b;
	}
	static void Show()     //_cdecl,无this指针
	{
		std::cout << "ma:" << ma << std::endl;
		//std::cout << "mb:" << mb << std::endl;        //不能访问普通成员变量
		std::cout << "mb:" << gdata << std::endl;     //可以访问全局变量
		//Print();                                    //静态成员方法不能调用普通成员方法
	}
	void Print()             //thiscall   this Test* const this
	{
		//std::cout << "ma:" << ma << std::endl;
		//std::cout << "mb:" << this->mb << std::endl;
		Show();                             //普通成员方法可以调用静态成员方法
	}
public:
	static int ma;
	int mb;
};

int Test::ma = 10;
int main()
{
	Test test1(10, 20);
	std::cout << sizeof(Test) << std::endl;
	std::cout << test1.mb << std::endl;
	std::cout << test1.ma << std::endl;
	Test::Show();
	test1.Show();
	return 0;
}

 

### 如何使用 `const` 修饰初始化类的成员变量 #### C++ 在C++中,当声明一个成员变量为`const`时,该成员变量必须在其定义处或通过构造函数的初始化列表来赋初值。一旦被赋予初始值,则不能再改变其值。 对于非静态成员,在构造函数中利用初始化列表完成这一操作是最常见的做法[^1]: ```cpp class CExample { public: CExample() : m_a(1), m_b(2) {} private: const int m_a; int m_b; }; ``` 而对于整型静态常量数据成员而言,可以直接于类体内指定默认值,这得益于这类成员具有编译时常量性质的特点[^2]: ```cpp class ExampleWithStaticConstMember { public: static constexpr int s_value = 42; // 静态常量成员可以在此直接初始化 }; ``` 另外,自C++11起引入了更灵活的方式——允许直接在类定义里给非静态成员设定初始值;不过需要注意的是,如果同时存在显式的初始化器(即初始化列表),那么后者会覆盖前者[^3]: ```cpp class Human { private: const std::string bloodType = "A"; // 类内初始化 }; ``` #### C# 相比之下,C#处理`const`字段的方式略有不同。在C#里面,`const`关键字用来创建真正的编译期常数,这意味着它的值不仅限定了不能更改,而且实际上是在程序运行前就已经确定下来并嵌入到最终生成的IL代码中的。因此,所有的`const`字段都必须立即给出具体的数值表达式作为其值,并且这个表达式应该能够完全由编译器计算得出结果。 下面是一个简单的例子展示如何在C#中定义和使用`const`: ```csharp public class Person { public const string BloodType = "O"; } ``` 值得注意的是,在C#中不存在像C++那样的初始化列表机制,所以任何需要动态决定的只读(`readonly`)而非真正意义上的常量(`const`)属性应当采用其他方式实现,比如通过构造函数参数传递并在实例化对象的时候设置相应的私有字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值