对象的初始化和构造函数:
对象名 A={1,2};该语句创建对象的同时为对象中的两个公有数据成员赋初值,但无法给private成员赋初值,此时通过公有成员函数赋初值,但是这种方法麻烦,所以使用构造函数。
简单地理解为构造函数是在定义对象A的时候就调用的函数,例如:对象名 A;就调用了一次构造函数,不需要额外的语句,用构造函数给对象赋值:
类内:student(double r,double l){a=r;b=l;}
主函数:student A(1.1,2.2);//这个语句就把1.1,2.2赋值给了私有数据成员A.a和A.b,除此之外,还可以用
主函数:student*A=new student(1.1,2.2)建立一个对象指针,虽然这个对象没有名字,但可以当对象来用,例如A->a可以用来访问a,与上面的A.a相同。记得在用完后delete pa;释放new出来的内存。
ps:构造函数名字与类名相同,无返回值,定义的时候直接 类名(形参),不需要在前面加void,函数内部也不需要return。
构造函数可以在类内定义也可以在类外定义,在类外定义,别的函数都是 double student::waight(形参) {} 这样的,但是构造函数只需要student::student{}
那么,当我们在定义对象的时候初始化数据成员的值的时候如果既使用 创建对象的同时为对象中的两个公有数据成员赋初值又使用上面提到的student A(1.1,2.2)给student构造函数赋形参会出现什么?答案是程序报错(本人亲测,如果有误请评论),两种方法不能同时使用,例如
#include <iostream>
using namespace std;
class student{
private:
int waight;
int tall;
//int hair;
public:
char sex;
student(int i,int r)
{
waight=i;
tall=r;
}
void print(student A1)
{
cout<<"性别是"<<A1.sex<<"体重是"<<A1.waight<<"身高是"<<A1.tall<<endl;
}
};
int main()
{
student A1(130,175)={'g'};
A1.print(A1);
return 0;
}
vscode无法通过编译
这说明两种在定义对象的同时初始化类的成员的方法不能混合使用(如果能混合使用欢迎评论批评)
当没有给类定义构造函数,系统默认生成构造函数,形式如下
student::student(){}//默认生成的构造函数的等价类外定义形式
构造函数也可以不带参数,直接在函数体内给成员赋值,这种方法赋的值来源于类里面,而带形参的时候来源于主函数等地方定义对象的时候传入的参数。
用成员初始化列标对数据成员初始化
上面的代码中的
student(int i,int r)
{
waight=i;
tall=r;
}
与
student(int i,int r): waight(i),tall(r)
{
}
是等价的,:右边的是成员初始化列表。
但本人认为成员初始化列表更加优越,因为
C++某些类型成员不允许在构造函数内赋值,例如const修饰的数据成员,此时却可以通过成员初始化列表赋值。
成员初始化列表使用需要谨慎:
student(int i,int r):A2(i),A1(r+A2)
{
}
private:
int A1;
int A2;
以上代码出错,因为A2的初始化在A1之后,数据成员的初始化是按照它们在类中的声明顺序进行的。
构造函数的重载:
class student{
private:
int hair,jump,run;
public:
student();
student(int,int,int);//重载函数类内声明可省略形参
void figure();
};
student::student()
{
hair=168;
jump=120;
run=3;
}
student::student(int a,int b,int c)
{
hair=a;
jump=b;
run=c;
}
inline void student::figure()
{
cout<<hair<<jump<<run<<endl;
}
int main()
{
student A1;
student A2(100,100,100);
A1.figure();
A2.figure();
return 0;
}
1681203
100100100
定义了一个无参构造函数和一个有参的,在主函数定义了A1,A2两个对象,A2使用上面提到的初始化成员的方法,结果A1.figure()结果为1681203,是无参构造函数内的
hair=168;
jump=120;
run=3;
100100100是A2的figure函数运行结果,这说明它将传入的三个100分别存入了三个成员数据,这与普通函数的重载有异曲同工之妙,调用什么函数由调用时的形式决定。
ps:调用无参构造函数用student A1;别用student A1();这样编译器以为你创建了一个A1函数,返回类型是student。
如果类里面定义了构造函数,系统将不再生成默认构造函数,此时在主函数内使用student A1;会出错。
带默认参数的构造函数:
class stu{
private:
int a,b;
public:
stu(int i=1,int j=2)//直接在括号里面给形参赋值
{
a=i;
b=j;
}
void addd()
{
cout<<(a+b)<<endl;
}
};
int main()
{
stu A;
A.addd();
return 0;
}
结果为:3
在构造函数内直接给形参赋值,这里赋的值是默认值,这里的构造函数仍然是默认构造函数,当我们主函数中把stu A;换成stu A(2,3);结果会变成5,可以理解为我们输入的初始值把默认值给覆盖(替换)了。
正因为带默认参数的构造函数仍然是默认构造函数,我们不能再重载一个不带参数的默认构造函数,也不能重载构造函数。
这个文章是我的个人笔记,专业性欠佳,大家一起学习,如果有错误请在评论区指出,感激不尽!