一、构造函数
- 构造函数是属于某一个类的
- 类是一种抽象的数据类型,它不占存储空间,不能容纳具体的数据,因此在类声明中不能给数据成员赋初值。
例如,下面的描述是错误的:
class Complex{
double real=0; //错误,在类声明中不能给数据成员赋初值
double imag=0; //错误,在类声明中不能给数据成员赋初值
};
如果一个类中的所有成员,都是公有的,则可以在定义对象时对数据成员进行初始化。
class Complex{
public:
double real;
double imag;
};
Complex c1={
1.1,2.2}; //定义类Complex的对象c1,将c1的数据成员real和imag分别初始化为1.1和2.2
如果类中包含私有的或保护的成员时,就不能用这种方法进行初始化。 这时,可以采用类中的公有成员函数来对对象中的数据成员赋初值,例如:
#include<iostream>
#include<cmath>
using namespace std;
struct Complex{
private:
double real; //复数的实部
double imag; //复数的虚部
public:
void init(double r,double i) //定义函数init,给real和imag赋初值
{
real=r;
imag=i;
}
double abscomplex(){
//定义函数abscomplex,求复数的绝对值
double t;
t=real*real+imag*imag;
return sqrt(t);
}
};
int main()
{
Complex A;
A.init(1.1,2.2);
cout<<"复数的绝对值是:"<<A.abscomplex()<<endl;
return 0;
}
但是,使用成员函数给数据成员赋初值既不方便也容易忘记,甚至可能出错,所以,C++利用构造函数来完成对象的初始化。
构造函数是一种特殊的成员函数,
构造函数作用: 为对象分配空间,对对象进行初始化,即对数据成员赋初值,这些数据成员通常为私有成员。
要求: ①构造函数的名字必须与类名相同,而不能由用户任意命名;
②它可以有任意类型的参数,也可以不带参数(不带参数的构造函数对对象的初始化是固定的)。但不能具有返回值类型,甚至也不能说明为void类型;
③它不需要由用户来调用,而是在建立对象时自动执行的,因此,“A.Complex(1.1,2.2);”这种用法是错误的;
④构造函数必须为公有类型,写在Public之下;
⑤与普通的成员函数一样,构造函数的函数体可写在类体内,也可写在类体外;
⑥在构造函数的函数体中不仅可以对数据成员赋初值,而且可以包含其它语句,但是,为了保持构造函数的功能清晰,一般不提倡在构造函数中加入与初始化无关的内容
⑦通常需要给每个类定义构造函数,如果没有给类定义构造函数,则编译系统自动地生成一个默认构造函数。 例如,编译系统为类Complex生成一个默认构造函数:Complex::Complex(){};
这个默认的构造函数不带任何参数,函数体是空的,它只能为对象开辟数据成员存储空间,而不能给对象中的数据成员赋初值。
例如,为类Complex建立一个构造函数。
class Complex{
private:
double real; //表示复数的实部
double imag; //表示复数的虚部
public:
Complex(double r,double i){
//定义构造函数,其名与类名相同
real=r; //在构造函数中,对私有数据real和imag赋值
imag=i;
}
double abscomplex(){
double t;
t=real*real+imag*imag;
return sqrt(t);
}
};
也可把构造函数的函数体写在类体外:
class Complex{
private:
double real; //表示复数的实部
double imag; //表示复数的虚部
public:
Complex(double r,double i); //声明构造函数原型
double abscomplex(); //声明成员函数原型
};
Complex::Complex(double r,double i){
//在类外定义构造函数
real=r;
imag=i;
}
double Complex::abscomplex()