频道栏目
首页 > 资讯 > C++ > 正文

C++的构造函数、析构函数、拷贝构造函数等代码实例讲解

18-07-19        来源:[db:作者]  
收藏   我要投稿

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");
}
相关TAG标签
上一篇:python及selenium自动化之selenium下载和环境搭建教程
下一篇:登录MySQL报错“Access denied for user 'root'@'localhost' (using password: YES”的解决方法
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站