构造函数与析构函数
一.构造函数
1. 特点:
函数名和类名完全相同
不能定义构造函数的类型(返回类型),也不能使用void
通常情况下公有函数,否则它不能被其他成员函数那样被显式的调用
构造函数被声明为私有有特殊的用途
构造函数可以有任意类型和任意个数的参数,一个类可以有多个构造函数(重载)
2. 默认构造函数
如果程序未声明,则系统会自动产生出一个不带参数的构造函数
3. 构造函数的重载
4. 构造函数与new运算符
5. 全局对象的构造函数先于main函数
Demo5.c
#ifndef _TEST_H_
#define _TEST_H_
class Test
{
public:
Test(int x, inty, int z);
~Test();
private:
int x_;
int y_;
int z_;
};
#endif
#include"Test.h"
#include<iostream>
usingnamespace std;
Test::Test(intx,int y, int z)
{
x_= x;
y_= y;
z_= z;
cout<<"bulidtest "<< x_<<endl;
}
Test::~Test()
{
cout<<"rmbuild test "<< x_<<endl;
}
#include"Test.h"
usingnamespace std;
intmain()
{
Testt1(1,2,3); //调用构造函数
t1.~Test(); //析构函数显式调用
Test*p = new Test(4,5,6); //调用构造函数
deletep; //调用析构函数 p存放在堆上,需手动释放,t1是局部变量,程序结束后会自动调用析构函数
return0;
}
构造函数 在定义对象/对象指针/数组时自动调用 ,做初始化
Testarray[3] = {Test(1,2,3)};
二.析构函数
1. 析构函数与数组
2. 析构函数与delete运算符
3. 析构函数显式调用
构造函数与析构函数顺序相反
三.转换构造函数
1. 单个参数的构造函数
将其他类型转换为类类型
2. 赋值与初始化区别
Test t = 10; //Test t(10); 初始化
t = 20; //赋值
调用转换构造函数构建一个临时对象Test(20),将临时对象赋值给t对象,析构临时对象
扩展——运算符重载
目的:C++中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。
3. excplice关键字
是转换构造函数不生效
4. 构造函数初始化列表
对象成员(对象所对应的类没有默认构造函数)的初始化,也只能在构造函数初始化列表中进行
const成员的初始化只能在构造函数初始化列表中进行
引用成员的初始化也只能在构造函数初始化列表中进行
class Test
{
private:
const int num;
int & count;
};
Test ::Test(int x) : x_(x) ,num(x) , count(x)
一个成员含有另一个成员的对象,成员对象的构造函数先语本身对象的构造函数的调用
5. 枚举对象适用与所有对象
枚举变量的访问方式
Test::SUCCESS
Demo6.c
#include <iostream>
using namespace std;
class Complex
{
public:
Complex(); //默认构造函数1
Complex(double r); //转换构造函数2
Complex(double r, double i) ;//构造函数3
Complex& operator + (constComplex &other);
void displaySum();
private:
double real;
double vir;
};
Complex::Complex ():real(0),vir(0)
{
cout<<"build 1 test!"<<endl;
}
Complex::Complex (doubler):real(r),vir(0)
{
cout<<"build 2 test!"<<endl;
}
Complex::Complex (doubler,double i):real(r),vir(i)
{
cout<<"build 3 test!"<<real<<" "<<vir<<endl;
}
Complex& Complex ::operator+ (const Complex &other)
{
return Complex(real + other.real,vir + other.vir );
}
void Complex::displaySum()
{
cout<<real;
if(vir > 0)
cout<<"+";
if(vir != 0)
cout<<vir<<"i"<<endl;
}
int main()
{
Complexa(10,10);
Complexb(20,-20);
Complex sum;
sum = a + b;
sum.displaySum();
return 0;
}
四.拷贝构造函数
功能:使用一个已经存在的对象来初始化一个新的同一类型的对象
声明:只有一个参数并且参数为该类对象的引用
如果类中没有说明拷贝构造函数则系统自动生成一个缺省复制构造函数,作为该类的公有成员
Demo7.c
[html] view plain copy
1. <span style="font-family:FangSong_GB2312;font-size:18px;"><strong>Test.h:
2. #ifndef _TEST_H_
3. #define _TEST_H_
4. class Test
5. {
6. public:
7. enum Result
8. {
9. success = 1,
10. failed = -1
11. };
12. Test(int x);
13. Test();
14. ~Test();
15. Test(const Test &other);
16. Test& operator = (const Test &other);
17. private:
18. int x_;
19. const int num_;
20.};
21.
22.#endif
23. Test.cpp:
24.#include "Test.h"
25. #include <iostream>
26.
27. using namespace std;
28.Test::Test() :num_(0)
29. {
30. cout << "default Test!" << endl;
31. }
32.Test::Test(int x) : x_(x),num_(x)
33. {
34. x_ = x;
35.
36. cout << "init Test!" << x_ << endl;
37. }
38.Test::Test(const Test &other) : x_(other.x_), num_(2)
39. {
40. cout << "copy Function!" << endl;
41. }
42.Test::~Test()
43. {
44. cout << "destory Test!" << x_ << endl;
45. }
46.
47. Test& Test :: operator = (const Test &other)
48.{
49. if (this == &other)
50. {
51. return *this;
52. }
53. this->x_ = other.x_;
54.
55. cout << "operator = !" << endl;
56.
57. return *this;
58.}
59. Main.c
60.#include <iostream>
61. #include "Test.h"
62.
63. using namespace std;
64.
65. int main()
66.{
67. Test t1(5);
68. Test t2(t1);
69.
70. return 0;
71. }</strong></span>
拷贝构造函数的调用情况
·用已有对象初始化对象会调用拷贝构造函数
·当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用
·当函数的返回值是类对象,函数执行完成返回调用者时使用