构造函数的初始化列表

     构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。

例如:

#include<iostream>

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;
}

 结果为:

从结果中,我们可以看出,初始化的顺序和初始化列表的顺序无关,仅仅和声明有关。

需要初始化的数据成员是对象的情况:

1.数据成员是对象,并且这个对象只有含参数的构造函数,没有无参数的构造函数;

        如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错

#include<iostream>
class Date
{
public:
	Date(int y, int m, int d)
	{
		year = y;
		month = m;
		day = d;
	}
public:
	int year;
	int month;
	int day;
};
class Stu
{
public:
	Stu(char* name, int id, int age, int y, int m, int d):
		birth(y, m, d)//调用birth对象中,带有三个参数的构造函数,对其初始化
	{
		mname = new char[strlen(name) + 1];
		strcpy(mname, name);
		mid = id;
		mage = age;
	    birth = Date(y, m, d);//调用赋值运算符重载函数
	}
	
	void show()
	{
		std::cout<< mname<<std::endl;
		std::cout<< mid<<std::endl;
		std::cout<< mage<<std::endl;
		std::cout<< birth.year<<std::endl;
		std::cout<< birth.month<<std::endl;
		std::cout<< birth.day<<std::endl;
	}
private:
	char* mname;
	int mid;
	int mage;
	Date birth;//成员对象
};
int main()
{

	Stu stu1("zhangsan", 1, 20, 1998, 12, 12);
	stu1.show();
	return 0;
}

2.对象引用或者cosnt修饰的数据成员

        当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化,因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。

例子:

class Test
{
 priate:
    const int a;             //const成员声明
 public:
    Test():a(10){}           //初始化
};
或
class Test
{
 private:
     int &a;                  //声明
 public:
     Test(int a):a(a){}        //初始化
}

static修饰成员变量:

            不属于对象独享,属于对象共享,在类外要初始化,不依赖对象的访问

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

	}
public:
	static int ma;//修饰静态成员变量
	int mb;
};
int Test::ma = 100;//在类外初始化
int main()
{
	Test test1(10, 20);
	std::cout << sizeof(Test) << std::endl;
	std::cout << test1.mb << std::endl;
    std::cout << Test::ma << std::endl;//不依赖对象访问
	std::cout << test1.ma << std::endl;
	test1.Show();
	return 0;
}

 static修饰成员方法:

                如果static修饰成员方法,则是 _cdel调用约定,没有this指针;

                不能访问普通成员变量,只能访问静态成员变量和全局变量;

                静态成员方法不能调用普通成员方法,但是普通成员方法可以调用静态的成员方法。

#include<iostream>
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:" << mb << std::endl;
		std::cout << "mb:" << gdata << std::endl;
		Show();//可以调用静态成员变量和方法
	}
public:
	static int ma;
	int mb;
};
int Test::ma = 100;
int main()
{
	Test test1(10, 20);
	std::cout << test1.mb << std::endl;
	std::cout << Test::ma << std::endl;
	std::cout << test1.ma << std::endl;////不依赖与对象访问
	Test::Show();//不依赖与对象访问
	test1.Show();
	return 0;
}

常对象和常方法 

        1.常对象不能调用普通方法

         2.常对象能调用常方法

        3.普通对象可以调用常方法

        4.普通函数可以调用常方法

        5.常函数不能调用普通方法

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

#include<iostream>

class Test
{
public:
	Test(int a, int b) : mb(b), ma(a)//this Test* const
	{}
	//void Show()//错误,常对象不能调用普通方法
	 void Show() const// Test* const this   const
	{
		//.Print();//错误,常函数不能调用普通函数
		std::cout << "ma:" << ma << std::endl;
		std::cout << "mb:" << mb << std::endl;
	}
	void Print()// Test* const this
	{
		std::cout << "hello world !" << std::endl;
		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
	//test2.Print();错误,常对象不能调用普通方法
	return 0;
}

 

C++构造函数初始化列表是一种在构造函数初始化类成员变量和基类构造函数的特殊语法。它以冒号(:)开始,后跟一个或多个初始化项,每个初始化项由成员变量名或基类名和构造参数列表组成,各项之间用逗号分隔。 构造函数初始化列表的主要优势如下: 1. 效率更高:对于成员变量的初始化,尤其是const成员变量或引用类型的成员,构造函数初始化列表是必须使用的。与在构造函数体内赋值相比,初始化列表直接调用构造函数或赋值运算符来初始化成员变量,避免了不必要的拷贝或赋值操作,提高了效率。 2. 避免空缺问题:当成员变量为const或引用类型时,它们必须在构造函数中被初始化,因为它们不能被赋值。此时,初始化列表是唯一选择。 3. 对象的成员如果是类对象,使用初始化列表可以直接调用相应类的构造函数进行初始化,而不需要先默认构造再赋值,从而提高效率。 使用示例: ```cpp class Base { public: int baseValue; Base(int b) : baseValue(b) {} // 基类构造函数使用初始化列表 }; class Derived : public Base { public: int derivedValue; Derived(int b, int d) : Base(b), derivedValue(d) {} // 继承自Base,并初始化Derived的成员变量 }; ``` 在这个例子中,Derived类的构造函数使用初始化列表先调用基类Base的构造函数初始化基类部分,再初始化自己特有的成员变量derivedValue。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值