构造函数与对象初始化
构造函数用于创建类对象,初始化其成员。
析构函数用于撤销类对象。
对象的私有数据成员初始化
若对象定义时若未显式初始化,与变量类似,全局对象和静态对象在定义时初值为0,局部对象在定义时初值为不确定的值。一旦建立一个对象,对象通常都需要有一个有意义的初值。
1.在类中定义一个具有初始化功能的成员函数。每当创建一个对象时,就调用这个成员函数,实现初始化。
实例
#include <iostream>
using namespace std;
class computer//计算器类定义
{//默认访问权限是私有
int op1;//操作数
char ch;//运算符
int op2;//操作数
public:
void Set(int b,char d,int c)
{ op1=b; ch=d; op2=c;}
void Show();
void Init()
{op1=3; ch='+';op2=5; }
};
void computer::Show()//成员函数类外定义
{ switch(ch)
{ case '+':cout<<op1+op2<<endl;break;
case '-':cout<<op1-op2<<endl;break;
case '*':cout<<op1*op2<<endl;break;
case '/':if(op2==0) cout<<"不能被0除"<<endl;
else cout<<op1/op2<<endl;
break;
default:cout<<"运算符有错"<<endl;
}
}
int main()
{
computer a;//定义对象
a.Init();//通过成员函数进行对象初始化
a.Show();//计算并输出结果
return 0;
}
void Init()
{op1=3; ch='+';op2=5; }
computer a;//定义对象
a.Init();//通过成员函数进行对象初始化
2.建立对象的同时,自动调用构造函数,省去上述麻烦,使定义类对象时包含了为对象分配存储空间和初始化的双重任务。这种实现机制较为理想。
由于类的唯一性和对象的多样性,因此C++ 规定构造函数与类同名。其特点是:
①构造函数的作用是在对象被创建时使用特定的值构造对象,或者说将对象初始化为一个特定的状态。
②在对象创建时由系统自动调用。
③如果程序中未声明,则系统自动产生出一个缺省形式的构造函数。
④构造函数可以有参数,也可重载。可以为内联函数、重载函数、带默认形参值的函数。
⑤构造函数无返回类型,但是不要加void。
C++ 规定,每一个类必须有一个构造函数,没有构造函数就不能创建任何对象。
若未定义一个类的构造函数,则C++ 提供了一个缺省的构造函数,该缺省构造函数是一个无参数的构造函数,仅仅负责创建对象,而不做任何初始化工作;
只要一个类定义了一个构造函数,C++ 就不再提供缺省的构造函数。如还需要无参数构造函数,则必须自己定义;
与变量定义类似,在用缺省构造函数创建对象时,如果创建的是全局对象或静态对象,则对象成员数据全为0;局部对象创建时,其成员数据是无意义的随机数。
实例
#include <iostream>
using namespace std;
class computer//计算器类定义
{//默认访问权限是私有
int op1;//操作数
char ch;//运算符
int op2;//操作数
public:
void Set(int b,char d,int c)
{ op1=b; ch=d; op2=c; }
void Show();
computer(int b,char d,int c)
{op1=b; ch=d;op2=c; }
};
void computer::Show()//成员函数类外定义
{ switch(ch)
{ case '+':cout<<op1+op2<<endl;break;
case '-':cout<<op1-op2<<endl;break;
case '*':cout<<op1*op2<<endl;break;
case '/':if(op2==0) cout<<"不能被0除"<<endl;
else cout<<op1/op2<<endl;
break;
default:cout<<"运算符有错"<<endl;
}
}
int main()
{
computer a(3,'+',5);//定义对象并初始化
a.Show();//计算并输出结果
return 0;
}
computer(int b,char d,int c)
{op1=b; ch=d;op2=c; }
computer a(3,'+',5);//定义对象并初始化
注意:构造函数可采用以下两种方式将值赋给其成员。
1、在构造函数体内进行成员变量的赋值,如例3.2所示,
computer(int b,char d,int c)
{ op1=b; ch=d; op2=c; //在函数体内赋值
}
2、使用函数体前的初始值表,例如:
computer(int b,char d,int c):op1(b),ch(d),op2(c){ }
this指针
在每个类的成员函数中,都隐含了一个this 指针,该指针指向正在调用成员函数的对象。如下所示:
computer(int op1,char ch,int op2)
{this->op1=op1;
this->ch=ch;
this->op2=op2;
}
computer构造函数中:3个形参与数据成员同名,所以使用this指针进行区别。如果不同名,可以不用this指针进行区分。类的其他成员函数碰到形参与数据同名的情况,也用this指针进行同样的区分。
无参构造函数进行对象初始化的实例
#include <iostream>
using namespace std;
class computer//计算器类定义
{//默认访问权限是私有
int op1,op2;//两个操作数
char ch;//运算符
public:
void Set(int b,char d,int c)
{ op1=b;op2=c;ch=d; }
void Show();
computer(int b,char d,int c)//带参构造函数
{op1=b;ch=d;op2=c; }
computer()//无参构造函数
{op1=3;ch='+';op2=5; }
};
//构造函数重载。C++ 根据对象定义时所带参数类型和个数选择合适的构造函数
void computer::Show()//成员函数类外定义
{switch(ch)
{case '+':cout<<op1+op2<<endl;break;
case '-':cout<<op1-op2<<endl;break;
case '*':cout<<op1*op2<<endl;break;
case '/':if(op2==0) cout<<"不能被0除"<<endl;
else cout<<op1/op2<<endl;
break;
default:cout<<"运算符有错"<<endl;
}
}
int main()
{
computer a(9,'/',2),b;//定义对象并初始化
//如果要定义一个不带参数的对象b,则会调用无参构造函数完成对象初始化的工作
a.Show();//计算并输出结果
b.Show();//计算并输出结果
return 0;
}
函数重载:
一组参数和返回值不同的函数共用一个函数名。
注意: 重载函数之间必须在参数的类型或个数方面有所不同。只有返回值类型不同的几个函数不能重载。
int add(int x, int y);
形参类型不同
float add(float x, float y);
int add(int x, int y);
形参个数不同
int add(int x, int y, int z);
注意:由于类名是成员函数名的一部分,所以一个类的成员函数与另一个类的成员函数即使同名,也不认为是重载,因为不同作用域。
重载函数的形参必须不同: 个数不同或类型不同。编译程序将根据实参和形参的类型及个数的最佳匹配来选择调用哪一个函数。
不要将不同功能的函数声明为重载函数,以免出现调用结果的误解、混淆。
带默认形参值的函数
函数定义时,可在形参列表中预先给一些默认值
当调用这种函数时,若为相应参数给出实参,则用实参初始化对应形参;如果没给出,则自动采用预先给定的默认形参值。
注意:
要保证所有的缺省参数均放在参数表的最后,即默认参数值必须按从右向左的顺序声明。如:
void func(int x, int n1 = 1, int n2 = 2);
默认形参值与函数的调用位置
调用出现在函数体实现之前时,缺省形参值必须在函数原形中给出;而当调用出现在函数体实现之后时,缺省形参值需在函数实现时给出。
带默认值构造函数进行对象初始化
#include <iostream>
using namespace std;
class computer//计算器类定义
{//默认访问权限是私有
int op1,op2;//两个操作数
char ch;//运算符
public:
void Set(int b,char d,int c)
{ op1=b;op2=c;ch=d; }
void Show();
computer(int b=3,char d='+',int c=5)//带默认值的构造函数
{op1=b;ch=d;op2=c; }
};
//带参构造函数和无参构造函数可以合并定义,用一个带默认值的构造函数定义即可
void computer::Show()//成员函数类外定义
{switch(ch)
{case '+':cout<<op1+op2<<endl;break;
case '-':cout<<op1-op2<<endl;break;
case '*':cout<<op1*op2<<endl;break;
case '/':if(op2==0) cout<<"不能被0除"<<endl;
else cout<<op1/op2<<endl;
break;
default:cout<<"运算符有错"<<endl;
}
}
int main()
{ computer a(9,'/',2),b(9,'/'),c(9),d;//定义对象并初始化
a.Show();//计算并输出结果9/2=4
b.Show();//计算并输出结果9/5=1
c.Show();//计算并输出结果9+5=14
d.Show();//计算并输出结果 3+5=8
return 0;
}