C++的构造函数、析构函数、拷贝构造函数等代码实例讲解
#define _CRT_SECURE_NO_WARNINGS #include#include
#include#include //指针指存储的是变量的内存地址 //引用是变量的别名 using namespace std; /* struct Teacher{ char* name; int age; }; //引用 void my_print(Teacher& t){ cout << t.name << t.age << endl; } //指针 void my_print2(Teacher* t){ cout << t->name << t->age << endl; } //引用的主要作用就是作为参数或者返回值 void main(){ struct Teacher t; t.name = "tom"; t.age = 20; my_print(t); my_print2(&t); system("pause"); }
*/ //指针引用,可以代替二级指针 /*struct Teacher{ char* name; int age; }; void print(Teacher** t){ Teacher* tm = (Teacher*)malloc(sizeof(Teacher)); tm->age = 20; *t = tm; } void print2(Teacher* &t){ t = (Teacher*)malloc(sizeof(Teacher)); t->age = 20; } void main(){ Teacher* t=NULL; //print(&t); print2(t); cout << t->age << endl; system("pause"); }*/
//指针常量,常量指针 /*void main(){ //如 0x0011(4) 0x0022(5) int a = 4, b = 5; //指针常量,不能改变地址的指针,但是可以修改它指向的内容 //0xff00(0x0011) int* const p1 = &a; //不能将0x0011修改为0x0022 //p1 = &b;会报错 *p1 = 5; //常量指针,指向常量的指针,内容不能修改 //0xff00(0x0011) const int* p2 = &a; //可以将0x0011修改为0x0022 p2 = &b; //这里会报错 //*p2 = 6; cout << a << endl; system("pause"); }*/
//1.单纯给变量取别名没有任何意义,作为函数参数传递,能保证参数传递过程中不产生副本 //2.引用可以直接操作变量,指针要通过取值(*p),间接操作变量,指针的可读性差 //常引用,类似于java中的final /*void print(const int& a){ cout << a << endl; } void main(){ int a = 4, b = 8; const int &c = a; const int &d = b; //这句话会报错,提示c不是一个可以修改的值 //c = d; print(c); system("pause"); }*/
//引用的大小 /*struct Teacher{ char* name; int age; }; void main(){ Teacher t; t.age = 10; //引用是变量地址的别名 Teacher & tt = t; Teacher* tp = &t; cout << sizeof(tt) << endl;//8 cout << sizeof(tp) << endl;//4 system("pause"); }*/
/*struct Teacher{ char* name; int age; }; void print(Teacher * t){ cout << t->name << "," << t->age << endl; } void print2(Teacher& t){ cout << t.name << t.age << endl; } void main(){ //这个就相当于0x0011((NULL的地址) Teacher *t1 = NULL; //这里不报错,就是说,传入的指针可能为NULL print(t1); //这里会报错,就是说,传入的引用的值不能为NULL,可以在传入前进行判断 //Teacher &t2 = NULL; //print2(t2); }*/
//函数的默认参数 //在有默认值的后面的参数必须有默认值 /*void print(int a, int b = 6, int c = 9){ cout << a << "," << b << "," << c << endl; } //函数的重载 void print(int a, bool is_good){ cout << a << "," << is_good << endl; } void main(){ //print(20); print(20, false); system("pause"); } */
//可变参数 //要想使用可变参数,必须至少有两个参数。 /*void func(int i, int ...){ //读取 依赖stdarg.h //可变参数指针 va_list args_p; //开始读取可变参数,第一个参数为va_lsit,第二个参数为i va_start(args_p,i); //获取可变参数的值 //这个读取的是从第二个参数开始的 int a=va_arg(args_p, int); int b = va_arg(args_p, int); int c = va_arg(args_p, int); cout << i<<","<
//循环读取 //第一个参数为后面可变参数的数量 /*void func(int count, ...) { va_list ap; //声明一个va_list变量 va_start(ap, count); //第二个参数表示形参的个数 int sum = 0; for (int i = 0; i < count; i++) { int value=va_arg(ap, int);//第二个参数表示形参类型 cout << value << endl; } va_end(ap); //用于清理 } void main(){ func(3, 20, 40, 30); system("pause"); }*/
//c++中的类 MyTeacher.h class MyTeacher{ public: char* name; int age; public: void setAge(int age); int getAge(); void setName(char* name); char* getName(); }; MyTeacher.c++ #include"MyTeacher.h" void MyTeacher::setAge(int age){ this->age = age; } int MyTeacher::getAge(){ return this->age; } void MyTeacher::setName(char* name){ this->name = name; } char* MyTeacher::getName(){ return this->name; } /*#include"MyTeacher.h" void main(){ MyTeacher t; t.name = "jack"; t.age = 20; cout << t.getName() << "," << t.getAge() << endl; system("pause"); }*/
/* class Teacher{ public: char* name; int age; public: //无参构造函数(写了,就会覆盖默认的无参构造函数) Teacher(){ cout << "无惨构造函数" << endl; } //有参构造函数会覆盖默认的构造函数 Teacher(char* name, int age){ this->name = name; this->age = age; cout << name << "," <<> /* class Teacher{ public: char* name; int age; public: //无参构造函数 Teacher(){ this->name = (char*)malloc(sizeof(100)); strcpy(name, "jack"); age = 20; cout << "无惨构造函数" << endl; } //析构函数 //当对象要被系统释放时,析构函数被调用 //作用:善后处理 ~Teacher(){ cout <<"析构函数"<< endl; //这里会报错, //free(this->name); } }; void func(){ Teacher t;//会先调无惨构造函数,然后调析构函数 } void main(){ func(); system("pause"); }*/
/*class Teacher{ public: char* name; int age; public: //无参构造函数 Teacher(){ this->name = (char*)malloc(sizeof(100)); strcpy(name, "jack"); age = 20; cout << "无惨构造函数" << endl; } //拷贝构造函数(值拷贝) //默认拷贝构造函数 就是值拷贝 Teacher(const Teacher & obj){ this->name = obj.name; this->age = obj.age; cout << "拷贝构造函数" << endl; } }; void fun(Teacher t){ } Teacher fun2(Teacher t){ return t; } void main(){ //不会调用拷贝构造函数 Teacher t; //如下情况才会调用拷贝构造函数 //1.声明时赋值 //Teacher t1 = t; //2.作为参数传入,实参给形参赋值 fun(t);//实际上执行了Teacher t=t; //3.作为函数返回值返回,给变量初始化赋值 Teacher t2=fun2(t);//执行了三次 拷贝构造函数 system("pause"); }*/
/*浅拷贝问题: 由于浅拷贝后的对象和对象操作的是同一地址, 所以如果在析构函数中释放对象的话,不管是浅拷贝的对象还是对象释放完对象后如果再次释放就会报错。 class Teacher{ private: char *name; int age; public: Teacher(char *name, int age){ this->name = (char*)malloc(100); strcpy(this->name, name); this->age = age; cout << "有参构造函数" << endl; } ~Teacher(){ cout << "析构" << endl; //释放内存 free(this->name); } void myprint(){ cout << name << "," << age << endl; } }; void func(){ Teacher t1("rose", 20); //这里发生了浅拷贝 Teacher t2 = t1; t2.myprint(); } void main(){ func(); system("pause"); }*/
//深拷贝 //深拷贝就是在拷贝时在内存中新开辟内存存放变量 class Teacher{ private: char *name; int age; public: Teacher(char *name, int age){ this->name = (char*)malloc(100); strcpy(this->name, name); this->age = age; cout << "有参构造函数" << endl; } //深拷贝 Teacher(const Teacher& obj){ int len = strlen(obj.name); this->name = (char*)malloc(len + 1); strcpy(this->name, obj.name); this->age = obj.age; } ~Teacher(){ cout << "析构" << endl; //释放内存 free(this->name); } void myprint(){ cout << name << "," << age << endl; } }; void func(){ Teacher t1("rose", 20); //这里发生了浅拷贝 Teacher t2 = t1; t2.myprint(); } void main(){ func(); system("pause"); }