网站找到后台了 如何破解账号 密码,什么网站做论坛签名,那个有那种网站,网站建设捌金手指专业12.2 构造与析构2.2.1 构造函数2.2.2 缺省构造函数2.2.3 构造函数的重载2.2.4 类型转换构造函数2.2.5 拷贝构造函数 2.2 构造与析构
2.2.1 构造函数
构造函数(constructor)是与类同名的特殊成员函数#xff0c;主要用来初始化对象的数据成员。
像上一个例子#xff0c;初始… 2.2 构造与析构2.2.1 构造函数2.2.2 缺省构造函数2.2.3 构造函数的重载2.2.4 类型转换构造函数2.2.5 拷贝构造函数 2.2 构造与析构
2.2.1 构造函数
构造函数(constructor)是与类同名的特殊成员函数主要用来初始化对象的数据成员。
像上一个例子初始化的类成员的时候就有点麻烦。
class X{...X (...) {//构造函数...}
}构造函数的特点
与类同名没有返回类型可以被重载由系统自动调用不允许在程序中显示调用
#include iostream
using namespace std;class Student{
private:string m_name;int m_age;int m_no;
public:Student(const string name, int age, int no) {m_name name;m_age age;m_no no;}/*类内声明*/void set_name(const string name);void set_age(int age);void set_no(int no);void eat(const string food);void who();
};/*类外定义*/
void Student::set_name(const string name){m_name name;}
void Student::set_age(int age) {m_age age;}
void Student::set_no(int no){m_no no;}
void Student::eat(const string food){cout 我今天吃了 food endl;}
void Student::who() {cout 我叫: m_name 今年: m_age 学号: m_no endl;}int main(void) {Student s1(王钢蛋, 18, 2203);s1.who();s1.eat(烙饼);return 0;
}2.2.2 缺省构造函数
缺省构造函数也称无参构造函数但其未必真的没有任何参数为一个有参构造函数的每个参数都提供一个缺省值同样可以达到无参构造函数的效果
注意
如果一个类没有定义任何构造函数那么编译器会为其提供一个缺省构造函数 对基本类型的成员变量不做初始化对类类型的成员变量成员子对象将自动调用相应类的无参构造函数来初始化
#include iostream
using namespace std;class A{public:int m_i;A(void){cout A 的无参构造 endl;m_i 123;}
};class B{
public:int m_j; //基本类型成员变量A m_a; //类类型成员变量成员子对象
};
1
int main() {B b; //调用成员对象m_a的无参构造函数 调用B的缺省构造函数cout b.m_j endl; //未知cout b.m_a.m_i endl; //123return 0;
}如果一个类定义了构造函数无论是否有参数那么编译器都不会再提供缺省构造函数
2.2.3 构造函数的重载
#include iostream
using namespace std;struct param{int l, w, h, ww;
};class Desk{
public:int length, width, height, weight;Desk(int l, int w, int h, int ww) {cout Desk(int,int,int,int) endl;}Desk(void) {cout Desk(void) endl;}Desk(param p){cout Desk(param ) endl;}
};int main(void) {Desk d1(1,2,3,4);Desk d2;param pm;pm.l 1;pm.w 2;pm.h 3;pm.ww 4;Desk d3(pm);return 0;
}某些重载的构造函数具有特殊的含义
缺省构造函数按缺省方式构造类型转换构造函数从不同类型的对象构造拷贝构造函数从相同类型的对象构造
2.2.4 类型转换构造函数
将其他类型转换为当前类类型需要借助转换构造函数Conversion constructor转换构造函数只有一个参数。
#include iostream
#include cstring
using namespace std;class Integer {private:int m_i;
public:Integer(void){cout Integer(void) endl;m_i 3;}explicit Integer(int n) {cout Integer(int) endl;m_i n;}explicit Integer(const char *str){cout Integer(const string ) endl;m_i strlen(str);}void print(){cout m_i endl;}
};int main(void) {Integer i;i.print();//Integer j 5; //编译器会找参数为int类型的构造函数Integer j Integer(5); //编译器会找参数为int类型的构造函数j.print();//Integer k hello;Integer k Integer(hello);// 这样会更清晰调用的是那个构造函数k.print();return 0;
}explicit关键字就是告诉编译器需要类型转换时强制要求写程如下形式
Integer j Integer(5);
//Integer j 5; //error2.2.5 拷贝构造函数 用一个已定义的对象构造同类型的副本对象将调用该类的拷贝构造函数 class A{A(const A that){ //拷贝构造函数 注意参数必须是常引用...}
};A a;
A b(a);//调用拷贝构造
A c a;//调用拷贝构造案例 #include iostream
using namespace std;class Data{
public:int m_data;Data(int data 3){cout Data(int) endl;m_data data;}Data(const Data that){ //拷贝构造函数cout Data(const A) endl;m_data that.m_data;}
};int main(void){Data A1;Data A2(A1); //编译器会调用拷贝构造函数Data A3 A1;return 0;
}如果一个类没有显示定义拷贝构造函数那么编译器会为其提供一个缺省拷贝构造函数 对基本类型成员变量按字节复制对类类型成员变量成员子对象调用相应类的拷贝构造函数 class User {string m_name; //调用string类的拷贝构造函数int m_age; //按字节复制
};案例 #include iostream
using namespace std;class A{
public:int m_a;A(int m_a 0) { //缺省构造函数cout A(int) endl;}A(const A that){ //拷贝构造函数cout A(const A) endl;}
};class B{
public:A m_b;
};int main(void) {B b1; //调用A类中的缺省构造函数B b2 b1; //默认调用A类中的拷贝构造函数return 0;
}注意事项 拷贝函数的调用时机 用已定义对象作为同类型对象的构造实参以对象的形式向函数传递参数从函数中返回对象 拷贝构造过程风险高而且效率低设计时应尽可能避免 避免或减少对象的拷贝传递对象形式的参数时使用引用型参数从函数中返回对象使用引用函数返回值