构造函数和析构函数

#include<iostream>
#include<string>
using namespace std;
//对象的初始化和清理
//1 构造函数  进行初始化操作
class Person {public://构造函数Person() {cout << "Person 构造函数的调用;" << endl;}//析构函数~Person() {cout << "Person 析构函数的调用;" << endl;}
};
void test01() {Person p;
}
int main() {test01();return 0;
}

构造函数的分类和调用

#include<iostream>
#include<string>
using namespace std;
class Person {public://构造函数
public:int age;Person() {cout << "Person 默认构造函数的调用;" << endl;}Person(int n) {age = n;cout << "Person 有参构造函数的调用;" << endl;}//析构函数~Person() {cout << "Person 析构函数的调用;" << endl;}//拷贝构造函数Person(const Person &p) { cout << "Person 拷贝构造函数调用;" << endl;age = p.age;}
};
int main() {//括号法Person p1;//默认构造函数的调用Person p2(10);//有参构造函数的调用Person p3(p2);cout << "p2的年龄为:" << p2.age << endl;cout << "p3的年龄为:" << p3.age << endl;//注意事项//调用默认构造函数时,不要加()//不会创建对象 下面这行代码编译器会认为是一个函数的声明 不会认为在创建对象Person p();//显示法Person p1;             Person p2 = Person(10); //有参构造Person p3 = Person(p2);//拷贝构造Person(10);//匿名对象  特点:当前行执行结束后,系统会立即回收匿名对象//不要利用拷贝构造函数,初始化匿名对象  编译器会认为Person (p3)==Person p3;//Person(p3); //隐式转换法Person p4 = 10;//相当于 Person p4=Person(10);Person p5 = p4;return 0;
}

拷贝构造函数调用时机

c++中拷贝构造函数调用时机通常有三种情况

使用一个已经创建完毕的对象来初始化一个对象
值传递的方式给函数参数传值
以值方式返回局部对象

在这里插入代码片#include<iostream>
#include<string>
using namespace std;
class Person {public:int age;Person() {age = 0;cout << "Person 默认构造函数的调用;" << endl;}Person(int n) {age = n;cout << "Person 有参构造函数的调用;" << endl;}//析构函数~Person() {cout << "Person 析构函数的调用;" << endl;}//拷贝构造函数Person(const Person &p) { cout << "Person 拷贝构造函数调用;" << endl;age = p.age;}
};
//拷贝构造函数调用时机
//1 使用一个已经创建完毕的对象来初始化一个新对象
void test01() {Person p1(20);Person p2(p1);cout << "p2的年龄为:" << p2.age << endl;
}
//2 值传递的方式给函数参数传值
void doWork(Person p) {}
void test02() {Person p;doWork(p);    //实参传递给形参时会调用拷贝构造函数
}//3 值方式返回局部对象
Person doWork2() {Person p1;return p1;
}void test03() {Person p = doWork2();
}
int main() {//test01();//test02();test03();return 0;
}

构造函数调用规则

默认情况下,c++编译器至少给一个类添加三个函数
1 默认构造函数(无参,函数体为空)
2 默认析构函数(无参,函数体为空)
3 默认拷贝构造函数,对属性进行拷贝

构造函数调用规则如下:
1 如果用户定义有参构造函数,c++不再提供默认无参构造,但是会提供
默认拷贝构造
2 如果用户定义拷贝构造函数,c++不再提供其他构造函数

深拷贝与浅拷贝

浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作

#include<iostream>
#include<string>
using namespace std;//深拷贝与浅拷贝
//浅拷贝带来的问题 堆区的内容重复释放
//浅拷贝带来的问题 用深拷贝来解决(重新写一个拷贝构造函数)
class Person {public:int mAge;//年龄int *mHeight;//身高   (把身高开辟到堆区)Person() {cout << "Person的默认构造函数调用" << endl;}Person(int age,int height) {mAge = age;mHeight=new int(height);  //用指针来接受堆区的数据cout << "Person的有参构造函数调用" << endl;}Person(const Person &p) {cout << "Person的拷贝构造函数调用" << endl;mAge = p.mAge;       //编译器内部写的 没问题//mHeight = p.mHeight; 编译器默认实现//深拷贝操作mHeight=new int(*p.mHeight);}~Person() {//析构代码,将堆区开辟数据做释放操作if (mHeight != NULL) {delete mHeight;mHeight = NULL;}cout << "Person的析构函数调用" << endl;}
};void test01() {Person p1(18,160);cout << "p1的年龄为:" << p1.mAge <<" 身高为:"<<*p1.mHeight<< endl;Person p2(p1);cout << "p2的年龄为:" << p2.mAge << " 身高为:" <<*p2.mHeight << endl;
}int main() {test01();return 0;
}
//如果有属性在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

c++构造析构函数专题相关推荐

  1. 【C++学习】对私有构造析构函数的思考:new一个类对象vs直接创建类对象

    前置知识: new的类对象需要手动delete.且使用堆空间.且只能用指针接收. 直接创建的类对象创建在栈中(或说堆栈).不需要手动delete,随着生存周期的结束(如所在的函数return了)而释放 ...

  2. 不要在构造和析构函数中使用虚函数

    前言 本文将讲解一个新手 C++ 程序员经常会犯的错误 - 在构造/析构函数中使用虚函数,并分析错误原因所在以及规避方法. 错误起因 首先,假设我们以一个实现交易的类为父类,然后一个实现买的类,一个实 ...

  3. c++三大函数:拷贝构造(copy ctor)、拷贝赋值(copy op)、析构函数(dtor)

    Class的两个经典分类 Class without pointer member(s) complex Class with pointer member(s) string String clas ...

  4. iOS开发教程之OC语言-欧阳坚-专题视频课程

    iOS开发教程之OC语言-34296人已学习 课程介绍         Objective-C是扩充C的面向对象编程语言,iOS开发是用的Objective-C语言,本专题更系统的讲解Objectiv ...

  5. 对象特性--构造函数调用规则

    默认情况下,C++编译器至少给一个类添加3个函数: 1.默认构造函数(无参,函数体为空) 2.默认析构函数(无参,函数体为空) 3.默认拷贝构造函数,对属性进行值拷贝 1.创建一个类,C++编译器会给 ...

  6. 构造函数和析构函数的调用过程

    下面代码的输出是什么?(D) class A { public: A() { } ~A() { cout<<"~A"<<endl; } }; class B ...

  7. C语言的构造函数与析构函数

    C++和JAVA中有构造/析构函数,C语言中也有实现的方法,在gcc下可以使用关键字 __attribute__指定构造函数或者析构函数.他们由编译器在编译阶段进行处理. 声明构造函数: void _ ...

  8. C++ 构造函数和析构函数

    编译器会默认的添加构造函数和析构函数操作 系统默认会提供默认构造,拷贝构造,析构函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> ...

  9. C++ - 构造和析构 2018-01-10

    /*回顾上节的内容:1.实现中的事情 物 ->类 <属性 -> 成员变量> <行为 -> 成员函数>2.访问权限 public private (protec ...

最新文章

  1. Django(五)模型(model)系统 -- 常用字段和字段参数
  2. JavaScript基础JavaScript的常用编码惯例(007)
  3. nginx thinkphp 配置pathinfo
  4. AppleWatch开发-AlertController
  5. **bootstrap常见常用样式总结
  6. JQuery常用选择器总结
  7. 使用MegaCli工具,在线调整raid配置
  8. ROS 教程之 navigation : 用 move_base 控制自己的机器人(1)
  9. 人工智能芯片与传统芯片的区别
  10. ab压力 failed_ab测试时结果显示大量Request failed的情况分析
  11. 博客版面设计~文章填充
  12. Linux故障解决(3)——YUM安装任何软件 报错:ERROR: XZ COMPRESSION NOT AVAILABLE
  13. 90%的人都做错的用户画像,到底应该怎么做?
  14. QObject类 moc处理后代码
  15. 菜鸟抓鸡--各个端口的***总结
  16. MAPDF.NET 电子书合集
  17. android 平板端应用商店,安卓平板电脑软件商店--乐商店是目前最安全的Android应用商店...
  18. 鸿蒙系统u盘制作,WINDOWS系列 篇二:【保姆级】Windows 10安装版原版系统U盘制作及系统安装教程...
  19. 从pdf提取图片,有两个库可以提取fitz(要install pymupdf)、pdfminer(install pdfminer3k)
  20. iOS 苹果企业账号申请流程

热门文章

  1. Bryanyzhu对比学习串烧
  2. Rejecting re-init on previously-failed class java.lang.Class<androidx.core.view.ViewCompat$2>: java.
  3. 《Principle of Communications》学习笔记
  4. Mac上MySQL之初始化密码操作
  5. 8张图理解Java---importnew---programcreek
  6. javascript中的循环和遍历
  7. 《数据库系统概论》之数据库设计六步骤(需求、概念、逻辑、物理、实施、运行维护)
  8. vue学习DAY02
  9. 音乐与计算机摘要,音乐教育论文摘要_论文摘要_论文摘要范例
  10. C++中字符串的比较,compare()函数