构造函数详细介绍

构造函数基本概念
  1. 名字和类名相同,可以有参数,不能有返回值
  2. 作用是对对象进行初始化,如给成员变量赋值
  3. 如果定义类时,没有写构造函数,则编译器生成一个无参的构造函数,不进行任何操作
  4. 如果用户自己定义了构造函数,则编译器不再生成构造函数
  5. 对象生成时构造函数被调用,对象一旦生成,就再也不在其上执行构造函数了
  6. 一个类可以有多个构造函数
    重要:有时对象没有构造函数 被初始化就被使用会导致程序出错
调用默认构造函数

示例:

class Complex{private:double real, imag;public:void Set(double r, double i);
};
Complex c1; // 默认构造函数被调用
Complex *pc = new Complex;//默认构造函数被调用
调用用户自定义构造函数
class Complex{private:double real, imag;public:Complex (double r, double i=0);
}
Compelex::Complex(double r, double i){real = r;image = i;
}
Complex c1;   //error 缺少构造参数
Complex *pc = new Complex; // error,没有参数
Complex c1(2); //ok
Conplex c1(2, 4), c2(3,5); 
Complex *pc = new Complex(3, 4);

不难看出,当用户定义了自定义构造函数的时候初始化就必须按照用户定义的构造函数来,否则就会报错

可以有多个构造函数,参数个数或类型不同
class Complex{private:double read, imag;public:void Set(double r, double i);Complex(double r, double i);Complex(double r);Complex(Complex c1, Complex c2);
};
Complex::Complex(double r, double i){real =r;image = i;
}
Complex::Complex(double r){real = r;i = 0;
}
Complex::Complex(Complex c1, Complex c2){real = c1.real + c2.real;imag = c1.imag + c2.imag;
}
Complex c1(3), c2(1,0), c3(c1,c2);
// c1 = {1,3}, c2 = {1, 0}, c3 = {4, 0}

构造函数最好是用public,private不能直接用来初始化对象

构造函数在数组中的使用
class Csample{int x;public:CSample(){cout << "Constructor 1 called" << endl;}CSample(int n){x = n;ocut << "Constructor 2 called" << endl;}
};
int main(){CSample array[2];     // 输出两个Constructor 1 calledcout << "step1" << endl;CSample array[2] = {4,5};  // 输出两个Constructor 2 calledcout << "step2" << endl;CSample array[3] = {3};   //先输出一个Constructor 2 called 再输出一个 Constructor 1 calledcout << "step3" << endl;CSample *array4 = new CSample[2];   // 输出两个Constructor 1 calleddelete []array4;return 0;
}
class Test{public:Test(int n){} //(1)Test(int n, int m){}   //(2)Test() {}  //(3)
Test array1[3] = {1,Test)(1,2)}; // 三个元素分别用(1),(2),(3)初始化
Test array2[3] = {Test(2,3), Test(1,2), 1};  //三个元素分别用(2)(2)(1)初始化
Test *pArray[3] = {new Test(4), new Test(1,2) }; // 两个元素用(1)(2)初始化
}
复制构造函数

特点

  1. 只有一个参数,即对同类对象的引用
  2. 形如X::X(X& )或X::X(const X&)其中的一个
  3. 如果没有定义复制构造函数则有编译器默认生成
    自动生成复制构造函数的情况
class Complex{private:double real, imag;
};
Complex c1;  // 调用无参的构造函数
Complex c2(c1);  // 调用缺省的复制构造函数

调用自定义复制构造函数

class Compelx{public:double real, imag;Compelx(){}Complex(const Complex &c){real = c.radl;imag = c.imag;cout << "Copy Constructor called";}
};
Complex c1;
Complex c2(c1);  // 调用自定义的复制构造函数

不允许有X::X(X)的构造函数

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

  1. 当用一个对象去初始化另一个对象的时候
Complex c2(c1);
Complex c2 = c1;
  1. 函数参数是A类对象,那么函数调用的时候,类A的复制构造函数会被调用
class A{public :A() {};A(A&a){cout << "Copy constructor called " << endl;}
};
void Func(A a1){}
int main(){A a2;Func(a2);return 0;
}
  1. 函数返回值是类A的对象,函数返回时,A的复制构造函数被调用
class A{public:int v;A(int n){ v = n; };A (const A & a){v = a.v;cout << "Copy constructor called " << endl;} 
}
A Func(){A b(4);return b;
}
int main(){cout << Func().v << endl;return 0;
}

对象间赋值并调用复制构造函数

// a1,a2 都是A的对象
a1 = a2;

常引用参数的使用

// 这样的函数调用时会发生复制构造函数的调用,开销比较大
void fun(CMyclass obj_){cout << "fun" << endl;
}
// 1. 可以考虑用CMclass &
// 2. 如果不想参数在函数中被修改则加上 const 关键字
void fun(CMyclass & obj){// 函数中任何试图改变obj值的语法都是非法的
}
类型转换的构造函数

目的

  1. 定义构造函数的目的是在于实现类型的自动转换
  2. 只有一个参数,而且不是复制构造函数的构造函数,被看作是转换构造函数
  3. 当需要的时候,编译系统会自动调用转换构造函数,建立一个无名的临时对象

显示类型转换构造函数

class Complex{public :double real, imag;expilcit Complex(int i){cout << "IntConstructor called " << endl;real = i;imag = 0;}Complex(double r, double i){ real =r, imag = i;}
}
int main(){Complex c1(7, 8);Complex c2 = Complex(12);  // 调用显示构造函数c1 = 9; // error, 9不能被自动转换成一个临时的Complex 对象c1 = Complex(9);cout << c1.real << "," << c1.imag << endl;return 0;
}

可隐式的构造函数

class Complex{public :double real, imag;Complex (int i){cout << "IntConstructor called " << endl;real  = i;imag = 0;}Complex (double r, double i) { real = r, iamg = i ;}
};
int main(){Compelx c1(7,8);Complex c2 = 12;c1 = 9;cout << c1.real << "," << c1.iamg << endl;return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部