c+学习记录(五)

构造函数


- 基本概念

  • 是成员函数的一种
  • 名字与类名相同,可以有参数,但不能有返回值(void也不行)。
  • 作用是对对象进行初始化,如给成员变量赋初值
  • 如果定义类时没有写构造函数,则编译器会生成一个默认的无参数的构造函数,默认的构造函数无参数,不做任何操作
  • 如果定义了构造函数,则编译器不生成默认的无参数的构造函数
  • 对象生成时构造函数自动被调用,对象一旦生成,就再也不能在其上执行构造函数
  • 一个类可以有多个构造函数

注:构造函数是在对象已经占有存储空间后,对里面进行初始化的工作


- 为什么需要构造函数

  • 构造函数执行必要的初始化工作,有了构造函数就不用专门再写初始化函数,也不用担心忘记调用初始化函数
  • 有时对象没被初始化,会导致程序出错

- 使用示例

  • 多个构造函数
class A{
private:
double real,imag;
public:
A(double r,double i);
A(double r);
A(A c1,A c2);
};
A::A(double r,double i)
{
real=r;imag=i;}
A::A(double r)
{real=r,imag=0;}
A::A(A c1,A c2)
{real=c1.real+c2.real;
imag=c1.imag+c2.imag;}
A c1(3),c2(1,0),c3(c1,c2)//对应的real和image:c1={3,0},c2{1,0},c3={4,0}
  • 构造函数在数组中的使用
class Test{
public:
Test(int n){}//(1)
Test(int n,int m){}//(2)
Test(){}//(3)
};
Test array1[3]={Test(1),Test(1,2)};//三个元素分别用(1),(2),(3)初始化
Test *p[3]={new Test(4),new Test(1,2)};//只生成两个对象!,这里只开了两个内存,剩下一个指针指向未知

复制构造函数

- 基本概念

  • 只有一个参数,即对同类对象的引用
  • 刑如X::X(X&)X::X(const X&),二者选一,常用后面一种
  • 若没有定义复制构造函数,则编译器会生成默认复制构造函数,完成复制功能
  • 若自己定义了复制构造函数,则默认复制构造函数不存在

- 复制构造函数起作用的三种情况

  • 当用一个对象去初始化同类的另一个对象时
    例如:complex c2(c1);complex c2=c1;等价,为初始化语句,非赋值语句,此时复制构造函数都起作用
  • 如果某个函数有个参数是类A的对象,那么该函数被调用时,类A的复制构造函数将被调用
    例:
class A
{
public:
A(){};
A(A&a){
cout<<"copy"<<endl;
}
};
void Func(A a1){}
int main(){
A a2;
Func(a2);
return 0;
}

最终程序输出“copy”,此时就会出现形参未必等于实参的情况。

  • 若函数的返回值是类A的对象,则函数返回时,A的复制构造函数会被调用
    例:
class A
{
public:
int v;
A(int n){v=n;}
A(const A &a){
v=a.v;
cout<<"copy"
}
};
A Func(){
A b(4);
return b;}
int main(){
cout<<Func().v<<endl;
return 0;
}

则输出的是:copy 4

注意:对象间的赋值并不导致复制构造函数的调用


常量引用参数的使用

void fun(A obj_){}
cout<<"fun"<<endl;
}
  • 这样的函数调用会引发复制构造函数的调用,开销比较大
  • 考虑用A & 引用类型作为参数
  • 为了避免不小心改动了不能修改的变量,可以考虑加上const关键字
原文地址:https://www.cnblogs.com/2002ljy/p/12248095.html