C++--day05
目录:
1. C的提高 1-131P 时间七天
2. C++的基础 132-286P 时间八天
3. C++的提高 287-378P 时间五天
4. C/C++的数据结构 379-482P 时间五天
5. C/C++的设计模式基础 483-540P 时间三天
视频资料:https://www.bilibili.com/video/av27904891?from=search&seid=10891514449061956870
P171 构造和析构的基础知识
构造函数
1、构造函数定义及调用
1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数;
2)构造函数在定义时可以有参数;
3)没有任何返回类型的声明。
2、构造函数的调用
自动调用:一般情况下C++编译器会自动调用构造函数
手动调用:在一些情况下则需要手工调用构造函数
析构函数
1、析构函数定义及调用
1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数
语法:~ClassName()
2)析构函数没有参数也没有任何返回类型的声明
3)析构函数在对象销毁时自动被调用
4)析构函数调用机制
2、C++编译器自动调用
#include<iostream> using namespace std; class Test { public: Test()//无参数 构造函数 { cout<<"我是构造函数"<<endl; } ~Test()//析构函数 { cout<<"我是析构函数"<<endl; } private: }; //给对象搭建一个舞台,研究对象的行为 void objplay() { //先创建的对象后释放 Test t1; Test t2; } void main() { objplay(); system("pause"); }
P172 构造和析构的用途演示
#include<iostream> using namespace std; class Test { public: Test()//无参数 构造函数 { a=10;//作用:完成对属性的初始化工作 p=(char *)malloc(100); strcpy(p,"aaa"); cout<<"我是构造函数"<<endl; } void printfP() { cout<<p<<endl; cout<<a<<endl; } ~Test()//析构函数 { if (p!=NULL) { free(p); } cout<<"我是析构函数"<<endl; } private: int a; char *p; }; //给对象搭建一个舞台,研究对象的行为 void objplay() { //先创建的对象后释放 Test t1; t1.printfP(); printf("分隔符\n"); Test t2; t2.printfP(); } void main() { objplay(); system("pause"); }
输出结果
P173 构造函数的调用(无参数和有参调用)
#include<iostream> using namespace std; class Test2 { public: Test2() //无参数构造函数 { m_a=0; m_b=0; cout<<"无参数构造函数"<<endl; } Test2(int a)//有参数构造函数 { m_a=a; m_b=0; cout<<"a:"<<m_a<<endl; printf("这是等号构造函数\n"); } Test2(int a,int b)//有参数构造函数 { m_a=a; m_b=b; cout<<"有参数构造函数"<<endl; } //赋值构造函数(copy构造函数) Test2(const Test2 &obj) { cout<<"我也是构造函数"<<endl; } public: void printT() { cout<<"普通成员函数"<<endl; } private: int m_a; int m_b; }; //调用有参数构造函数3种方法 void main() { //Test2 t1;//调用无参数构造函数 //1. 括号法 Test2 t1(1,2);//C++编译器自动的调用构造函数 t1.printT(); //2. c++对=操作符进行了功能增强 Test2 t2=(3,4,5); Test2 t3=5; //3. 直接调用构造函数 手动的调用构造函数 Test2 t4=Test2(1,2);//匿名对象(匿名对象的去和留) system("pause"); }
输出结果:
P175 为什么需要构造和析构函数
1、构造函数的调用方法:自动调用(按照规则调用)
2、显示的初始化类的属性或其他资源
#include<iostream> using namespace std; class Test3 { public: void init(int _a,int _b) { a=_a; b=_b; } protected: private: int a; int b; }; void main() { //类没有提供构造函数 C++编译器会自动给你提供一个默认的构造函数 //类没有提供copy构造函数 C++编译器会自动给你提供一个默认的copy构造函数 Test3 t1; t1.init(2,3); Test3 tArray[3]; tArray[0].init(1,2); tArray[1].init(1,2); tArray[2].init(1,2); //在这种场景之下 显示的初识化方案显得很蹩脚 Test3 t21;t21.init(1,2); Test3 t22;t22.init(1,2); Test3 t23;t23.init(1,2); Test3 tArray2[3]={t21,t22,t23}; //在这种场景下 满足不了编程需要 //Test3 tArray2[1999]={t21,t22,t23}; system("pause"); }
P176 copy构造函数调用时机1和2
#include<iostream> using namespace std; class Test4 { public: Test4() //无参数构造函数 { m_a=0; m_b=0; cout<<"无参数构造函数"<<endl; } Test4(int a)//有参数构造函数 { m_a=a; m_b=0; cout<<"a:"<<m_a<<endl; printf("这是等号构造函数\n"); } Test4(int a,int b)//有参数构造函数 { m_a=a; m_b=b; cout<<"有参数构造函数"<<endl; } //赋值构造函数(copy构造函数) Test4(const Test4 &obj) { cout<<"我也是构造函数"<<endl; m_b=obj.m_b+100; m_a=obj.m_a+100; } public: void printT() { cout<<"普通成员函数"<<endl; cout<<"m_a:"<<m_a<<endl; } private: int m_a; int m_b; }; //1. 赋值构造函数 用1个对象去初始化另外一个对象 void main_number1() { Test4 t1(1,2); Test4 t0(1,2); t0=t1;//用t1给t0 赋值操作和初始化是两个不同的概念 //第一种 调用方法 Test4 t2=t1;//用t1初始化t2 t2.printT(); system("pause"); } //2. 第二种调用时机 void main() { Test4 t1(1,2); Test4 t0(1,2); Test4 t2(t1);//用t1对象初始化t2对象 t2.printT(); }
P178 copy构造函数调用时机3
#include<iostream> using namespace std; class Location { public: Location( int xx = 0 , int yy = 0 ) { X = xx ; Y = yy ; cout << "Constructor Object.\n"<<endl ; } Location( const Location & p ) //拷贝构造函数 完成对象的初始化 { X = p.X ; Y = p.Y ; cout << "Copy_constructor called." << endl ; } ~Location() { cout << X << "," << Y << " Object destroyed." << endl ; } int GetX () { return X ; } int GetY () { return Y ; } private : int X , Y ; } ; //业务函数 形参是一个元素 void f ( Location p ) { cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ; } void mainobjplay() { Location a(1,2); Location b=a; //形参是一个元素,函数调用,会执行实参变量初始化形参变量 f(b);//b实参去初始化形参p,会调用copy构造函数 } void main() { mainobjplay(); system("pause"); }
输出结果: