1、类相关非成员函数
在实际编写代码中,有时候也会遇到一些额外的功能函数,例如某个功能函数是打印某个类中一个成员变量值,这种额外的功能函数虽然和这个类有点关系,但感觉这种函数又不应该定义在类里面,这种函数声明和定义可以放在该类成员函数的声明和定义的文件中。下面例子以打印学生信息函数的声明和定义进行说明。
在.h头文件中声明类、成员变量、成员函数和非成员函数,如下:
#ifndef __MAIN_H__
#define __MAIN_H__
class student
{
public:
int age;
int hight;
int weight;
int num;
void StuInitFunc(int stuAge, int stuHight, int stuNum, int stuWeight);
};
void StuInfoPrint(student& stu);//非成员函数
#endif // !__MAIN_H__
在.cpp文件中定义成员函数、非成员函数并通过main函数调用,如下:
#include#include #include #include"main.h" using namespace std; void student::StuInitFunc(int stuAge,int stuHight,int stuWeight,int stuNum) { age = stuAge; hight = stuHight; weight = stuWeight; num = stuNum; } void StuInfoPrint(student& stu)//非成员函数 { cout << "age = " << stu.age << endl; cout << "hight = " << stu.hight << endl; cout << "weight= " << stu.weight << endl; cout << "num = " << stu.num << endl; } int main() { student stu1; stu1.StuInitFunc(18,180,80,1001);//年龄:18,身高:180cm,体重:80kg,学号:1001 StuInfoPrint(stu1);//调用非成员函数 return 0; }
运行程序打印结果如下:
2、类内初始值
在C++新标准里,可以为新成员变量提供一个类内初始值,在创建类对象的时候,这个初始值用来初始化该成员变量。对于没有初始值的成员变量,系统有默认的初始策略,系统会给它们赋随机值,程序如下,
在.h头文件中这样声明和给age初始值:
#ifndef __MAIN_H__
#define __MAIN_H__
class student
{
public:
int age = 25;
int hight;
int weight;
int num;
void StuInitFunc(int stuAge, int stuHight, int stuNum, int stuWeight);
};
void StuInfoPrint(student& stu);
#endif // !__MAIN_H__
在.cpp文件中这样定义和调用,程序如下:
#include#include #include #include"main.h" using namespace std; void student::StuInitFunc(int stuAge,int stuHight,int stuWeight,int stuNum) { age = stuAge; hight = stuHight; weight = stuWeight; num = stuNum; } void StuInfoPrint(student& stu) { cout << "age = " << stu.age << endl; cout << "hight = " << stu.hight << endl; cout << "weight= " << stu.weight << endl; cout << "num = " << stu.num << endl; } int main() { student stu1; StuInfoPrint(stu1);//打印成员变量值。注:只有age被赋值为25,其它成员变量没有被赋值,系统会给它们赋随机值 cout << endl; stu1.StuInitFunc(18,180,80,1001);//给所有成员变量赋值。年龄:18,身高:180cm,体重:80kg,学号:1001 StuInfoPrint(stu1);//打印成员变量值 return 0; }
程序运行结果如下:
可以看到:
(1)第一次打印的几个成员变量值,除了在类声明中给age赋值为25,其它没有没有手动赋值,系统会给它们赋随机值。
(2)第二次打印的几个成员变量值,打印的值是我们通过传参赋的值,说明传参后会把原来初始化赋的值覆盖掉。
(3)如果使用构造函数初始化列表或在构造函数中给成员变量传参赋值,那么在类声明时已初始化的成员变量的值也会被覆盖掉。
3、const成员变量的初始化
对于类的const成员,只能使用初始化列表来初始化,而不能在构造函数内部进行赋值操作。如下类在声明时用const修饰成员变量,在定义构造函数中这样对成员变量赋值会报错。
类声明时用const修饰成员变量:
在定义构造函数中通过传参给成员变量赋值:
main函数创建类对象和调用构造函数:
编译后系统会报错,如下所示:
如果把上面的构造函数传参赋值改为初始化列表对成员变量进行初始化,则不会报错,如下:
student::student(int stuAge,int stuHight,int stuWeight,int stuNum):age(stuAge), hight(stuHight), weight(stuWeight), num(stuNum){}
特别注意:构造函数不能声明和定义为静态类型const。
四、默认构造函数
(1)如果一个类没有声明和定义构造函数或者构造函数是无参的构造函数,可以直接这样创建类对象:
student stu1;
(2)如果程序员在一个类中声明和定义了多个带参的构造函数,创建类对象时,类对象右侧必须跟带参的构造函数并提供与程序员书写构造函数参数相符合的实参,才能成功创建对象。
类和构造函数声明:
class student
{
public:
int age;
int hight;
int weight;
int num;
student(int stuAge, int stuHight, int stuNum, int stuWeight);
};
构造函数定义:
student::student(int stuAge,int stuHight,int stuWeight,int stuNum):age(stuAge), hight(stuHight), weight(stuWeight), num(stuNum)
{
}
类对象的创建:
int main()
{
//不能这样创建对象,会报错:类不存在默认构造函数。原来默认构造函数是无参构造函数,
//student stu1; //现在在类中声明和定义了有参构造函数,默认就是有参构造函数
student stu1 = student(18, 180, 80, 1001);//现在系统没有默认构造函数,需要根据程序员书写的构造函数传相应的实参,类对象才能创建成功
StuInfoPrint(stu1);//打印成员变量值。注:只有age被赋值为25,其它成员变量没有被赋值,系统会给它们赋随机值
return 0;
}
五、 "= default; "和" = delete;"
1、= default
我们举一个例子,
在.h头文件中这样声明:
#ifndef __MAIN_H__
#define __MAIN_H__
class student
{
public:
int age;
int hight;
int weight;
int num;
student(int stuAge, int stuHight, int stuNum, int stuWeight);
};
void StuInfoPrint(student& stu);
#endif // !__MAIN_H__
在.cpp文件中这样定义:
#include#include #include #include"main.h" using namespace std; student::student(int stuAge,int stuHight,int stuWeight,int stuNum):age(stuAge), hight(stuHight), weight(stuWeight), num(stuNum) { } void StuInfoPrint(student& stu) { cout << "age = " << stu.age << endl; cout << "hight = " << stu.hight << endl; cout << "weight= " << stu.weight << endl; cout << "num = " << stu.num << endl; } int main() { student stu1; //这里这样声明后编译不通过,会报错 student stu2 = student(18, 180, 80, 1001);//给所有成员变量赋值。年龄:18,身高:180cm,体重:80kg,学号:1001 StuInfoPrint(stu2);//打印成员变量值。注:只有age被赋值为25,其它成员变量没有被赋值,系统会给它们赋随机值 return 0; }
编译后系统报错,提示”student stu1”没有合适的构造函数可用,报错信息如下:
分 析:因为类中没有无参数的构造函数,所以程序报错。
解决办法:
(1)在书写类声明时,在类中添加这样一个语句:
student() = default;
(2)然后在main函数中这样创建类对象,不会报错,如下:
student stu1;
这样写了以后,student默认构造函数就带有了”=default”特性--编译器能够为这种”default”的函数自动生成函数体(等价于空函数体“{ }”)。开发者不用自己写默认构造函数体。
一般这种“=default”写法只适合一些比较特殊的函数,如默认构造函数(不带参数),普通成员函数就不能这样写。而带参数的构造函数,系统也不认为是特殊构造函数。
上面直接在书写类声明时添加student() = default;这条语句,这个无参构造函数就具备了inline特性。
在书写类声明时,这样书写把student() = default;修改为student();然后在.cpp文件中这样如下定义无参构造函数student,就不具备inline特性:
student::student() = default;
2、=delate;
这个写法是用来让程序员显示地禁用某个函数。
如果我们把上面的在类声明时书写的student() = default;或在无参构造函数定义的student::student() = default;中的default改为delete,意思就是让student类禁止使用无参构造函数student()。
2022.07.03结。



