#P1915. 构造函数.理论知识
构造函数.理论知识
1. 类的一些基本知识概念
C 语言已经有结构体了,在 C++ 里结构体被增加了大量的功能,就成了类。这两个东西是一脉相承的。C++ 里的结构体本质上就是类,只不过为了语法的延续,还保留了 struct
的语法,但是,它就是穿着 struct
外衣的 class
。
也就是说,你的程序虽然是用 struct 定义了一个结构体,但是它其实就是类,就是 class 。唯一一点点差别是,你用 struct
定义结构体(假结构体,实际上是类),默认所有的成员变量和成员函数都是 public
属性(就是允许外部访问),而用 class
定义的类,成员变量和成员函数默认是 private
属性(不允许外部访问)。
下面,用 struct 和用 class 定义出来的 stduent 是一样的东西。
// 基于结构体 定义 student
struct student
{
string name; // 姓名
bool gender; // 性别,ture 表示男,false 表示女
int yu,shu,ying; // 语数英成绩
};
// 虽然 student 是结构体,但是实际上它是类,C++ 内部就是把 stuct 当做 class 来处理
// 基于类 定义 student
class student
{
public:
string name; // 姓名
bool gender; // 性别,ture 表示男,false 表示女
int yu,shu,ying; // 语数英成绩
};
// 默认情况下,class 的所有成员都是 private 的,就是外部访问不到的,如果你不想这样,就要用 public 的属性
也正是因为 结构体 和 类 有这么密切的关系,所以,即便我们后面很多程序还是用 struct 语法,但是学到的东西基本上也适用于 class ,我们回答理论题的时候都可以把这种知识运用起来。
2. 类和面向对象编程
之所以要弄出类,就是为了大型软件开发项目的功能需要的。一个大型项目,不同的团队做不同的模块,一个团队做出来的模块可能会被别的团队用到,所以,需要代码重用、模块化,所以,继承,封装 这些功能就很重要。但是,这些东西太抽象,没有参加过大型项目的人很难理解这些东西。对于学生而言,参加比赛的程序就是短小精悍,不太需要代码稳健、可重用,自己看得懂就好了,所以结构化、可读性也不是太重要(对老师改作业来说是很重要的,你写成裹脚布一样老师就没法看)。
后面,我们会带着大家学一些面向对象编程的特性,我们没有时间单单为了学语法而学语法,就在学一些算法的时候,用面向对象编程的代码风格来演示给大家看。
3. 构造函数
构造函数是类的一个语法特性。构造函数是结构体或者类在做实例化的时候自动调用的函数,起到初始化的作用。
为什么要这样子做,主要是为了代码好管理。如果每一次初始化的时候都要写好多句,这几句反复出现在你的程序中,那么你就应该考虑把这个初始化的逻辑抽离出来,放到构造函数中了。
struct student
{
string name; // 姓名
bool gender; // 性别,ture 表示男,false 表示女
int yu,shu,ying; // 语数英成绩
}x[1000];
int n;
cin>>n;
string m_name;
int m_gender,m_yu,m_shu,m_ying;
for(int i=0;i<n;i++){
cin>>m_name>>m_gender>>m_yu>>m_shu>>m_ying;
x[i].name = m_name;
x[i].gender = (m_gender==1); // 输入数据里,1 表示 男,0 表示 女
x[i].yu = m_yu;
x[i].shu = m_shu;
x[i].ying = m_ying;
// 上面这么长长的一大段放在这个位置,其实是不太好的,会分散了写程序的人或者阅读程序的人的注意力
}
使用构造函数,上述的程序可以改成下面这个样子:
struct student
{
string name; // 姓名
bool gender; // 性别,ture 表示男,false 表示女
int yu,shu,ying; // 语数英成绩
student(string m_name,int m_gender,int m_yu,int m_shu,int m_ying){
name = m_name;
gender = (m_gender==1);
yu = m_yu;
shu = m_shu;
ying = m_ying;
};
student(){ }; // 这是无参数的构造函数
}x[1000];
int n;
cin>>n;
string m_name;
int m_gender,m_yu,m_shu,m_ying;
for(int i=0;i<n;i++){
cin>>m_name>>m_gender>>m_yu>>m_shu>>m_ying;
x[i] = student(m_name,m_gender,m_yu,m_shu,m_ying);
}
关于构造函数,入门级的一些基本要点是:
-
你定义一个结构体的时候,编译器会自动帮它选一个不带输入参数,而且什么都不做的构造函数(所以,其实即便你不定义构造函数,结构体都会有构造函数,只不过这个函数什么都不做),你千万不要以为你不写构造函数就真的没构造函数了
-
你如果定义了一个构造函数,那么编译器就不会再帮你选一个默认的构造函数了。定义数组的时候,它会去找一个,不带输入参数的构造函数,所以如果你不补一个,那就会报错。报错提示是:[Error] no matching function for call to 'student::student()
-
构造函数的名字是和结构体(类)的名字一样,不能改
-
不需要写构造函数的返回值类型,啥都不用写,包括你写 void 也不对,写结构体的名字也不对。
-
和构造函数相对应的另外一个函数叫
构析函数
,构析函数是在类实例(结构体实例)被销毁的时候执行的,它的名字是类的名字前加~
。