构造&析构函数

  构造函数

    定义:与类同名,可以有参可以无参,主要功能用于在类的对象创建时定义初始化的状态,无返回值,也不能用void修饰,构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用

      一个类若是只定义了私有的构造函数,将无法通过new关键字来创建其对象,若是没有定义,那么编译器会提供一个默认的构造函数,构造函数可以有多个,

    构造列表:即构造函数初始值列表,在构造列表中的变量是直接初始化,在函数体内的则是先调用默认构造函数初始化再赋值,这不仅事关底层效率问题,更重要的是一些数据成员必须初始化,

      在构造函数初始化顺序与它们在类定义中的出现顺序保持一致,一般来说初始化的顺序没什么特别要求,不过如果一个成员是用另一成员来初始化的,那么这两个成员的初始化顺序就很重要了

      如果可能,尽量避免用一个值来初始化另一个值

  explicit 修饰的构造函数必须显示调用,另外修饰的函数不能进行隐式转换。在C++中如果定义了参数列表中的参数,但是在函数内部却没有使用到,那么编译器会报参数没有使用的警告,

  拷贝构造函数

    定义:以同型对象初始化自我对象,一般类都会定义一个拷贝构造函数,一个拷贝构造函数,一个拷贝分配操作符,即使不需要也会定义为私有的不实现,以防编译器自己定义

      class Widget{

        public:                  //这里设置为public,是因为这里要使用,其他情况一般都设为private,且不实现

          Widget();                //default构造函数

          Widget (const Widget &rhs);        //copy构造函数

          Widget &operator = (const Widget &rhs);  //拷贝分配操作符,一般要返回一个指针的,不强制要求

          ...

        }

    Widget w1;                    //调用default构造函数

    Widget w2(w1);                  //调用拷贝构造函数

    w1 = w2;                      //调用分配操作符

    Widget w3 = w2;                  //调用拷贝构造函数,注意区分与拷贝赋值的关系

  析构函数

    定义:与构造函数相反,当对象结束其生命周期时,系统自动执行析构函数,析构函数与构造函数名相同,只是在函数名前加~以示区别,析构函数只有一个,不能重载,如果用户并没有定义,那么

      编译器也会自动生成一个缺省的析构函数,不要在析构函数中调用exit(),因为析构函数本身即会调用,若是主动调用exit(),则会陷入无限循环,由于析构函数能够自动进行类缺省的清理工作,

      如果调用成员或基类的析构函数一样,所以通常并不需要在析构函数的定义中显示地编写任何代码

    使用:一般情况下我们不直接调用析构函数,而如果我们需要调用析构函数里面的功能,那么建议将此功能写成一个普通的函数

  创建子类对象:此对象先调用基类的构造函数构造对象的基类部分,再调用子类的构造函数构造对象的子类部分

  销毁子类对象:此对象先调用子类的析构函数析构对象的子类部分,再调用基类的析构函数析构对象的基类部分

    总结:可以想象一下, 子类对象可以访问父类,如果在构造子类对象的子类部分时基类没构建完成,而子类就调用了基类的东西,那么肯定会出问题,所以构造要先构造对象的基类部分

        同理,析构时如果先析构子类对象的基类部分,那么在基类析构完成后子类如果再调用基类,那么也会出问题,所以析构要先析构对象的子类部分,就像盖楼从基层盖起,拆楼从顶层拆起

  友元函数

  定义:形如friend func1();使普通函数能够访问类的友元,实现位置可以在类外或类中,实现代码与普通函数相同,友元关系不能被继承是单向不具有交换性,在实现类之间数据共享时减少系统开销,

      提高效率等

  优点:能够提高效率,表达简单,清晰

  缺点:友元破坏了封装机制,尽量不使用友元

  声明:放在类的公有区和私有区都没有关系

  使用:1. 运算符重载的某些场合需要使用友元 2. 两个类要共享数据的时候

  实例:class INTEGER {

      friend void A::Print(const INTEGER &obj);  //声明这个类的友元函数,那么在其他地方调用这个函数就可以访问类的所有内容,声明时必须明确指出该成员函数属于哪个类

      friend class A;              //声明友元类

      };

      void Print(const InteGER &obj) {函数体}

      void main() {

        INTEGER obj;

        Print(obj);            // 调用友元函数

        }

      可以在一个头文件或源文件中定义多个类,然后将它们声明为各自的友元类,在源文件定义各自类中的函数时需要加域作用符

      在声明为某个类的友元之前,其必须是程序中的一个已经定义过的类,不能新声明一个类,然后说它是谁谁谁的友元

        public:void initialize();

        friend void g(X*, int);    // Global friend

        friend void Y::f(X*);      // Struct member friend

        friend struct Z;        //Entire struct is a friend

        friend void h();

        friend calss class-name

  new 和 delete

    C++的new和delete比C中的malloc和free要好得多,C++把创建一个对象所需的所有动作都结合在一个称为new的运算符里,当使用new创建一个对象时,它就在堆里为对象分配内存并为这块内存调用

    构造函数进行初始化,默认的new还进行检查以确信在传递地址给构造函数之前分配内存是成功的,所以不必显示地确定调用是否成功, Mytype *fp = new Mytype;只是一个简单的表达式,它带有

    内置的长度计算,类型转换,和安全检查,delete只用于删除由new创建的对象,如果是malloc或其他方式创建一个对象,然后由delete删除它,这个动作行为是未定义的,因为大多数默认的

    new和delete实现机制都使用了malloc和free,所以很可能会没有调用析构函数就释放了内存,如果正在删除的对象指针是0(即是空,NULL),则不会发生任何事情,因此建议在删除指针后把指针赋为空

    以免二次删除,对一个对象二次删除可能会产生某些问题

  关于作者

    姓名:张坤武

    邮箱:1498462303@qq.com

C++学习笔记 构造&析构 友元 new&delete的更多相关文章

  1. Effective C++学习笔记——构造/析构/拷贝运算

    条款9:决不再构造和析构过程中调用virtual函数,包括通过函数间接调用virtual函数. 应用:想在一个继承体系中,一个derived class被创建时,某个调用(例如生成相应的日志log)会 ...

  2. swift学习笔记之-析构过程

    //析构过程deist import UIKit /*析构过程(Deinitialization):析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标示 ...

  3. Scala学习笔记之:tuple、array、Map

    [TOC] 本文<快学Scala>的笔记 tuple学习笔记 tuple的定义 对偶是元组(tuple)的最简单形态--元组是不同类型的值的聚集. 元组的值是通过将单个值包含在圆括号中构成 ...

  4. 《Linux内核分析》第三周学习笔记

    <Linux内核分析>第三周学习笔记 构造一个简单的Linux系统MenuOS 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.stud ...

  5. C++学习笔记-继承中的构造与析构

    C++存在构造函数与析构函数,继承中也存在构造和析构函数.继承中的构造和析构函数与普通的构造析构有细微差别. 赋值兼容性原则 #include "iostream" using n ...

  6. 《Effective C++》第2章 构造/析构/赋值运算(2)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  7. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. CUBRID学习笔记 45 REPLACE DELETE MERGE 教程

    c#,net,cubrid,教程,学习,笔记欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com . 过错 ------ 官方文档是英文的, ...

  9. C++学习笔记之友元

    一.引言 C++控制对类对象私有部分(private)的访问,通常只能通过公有的(public)类方法去访问.但是有时候这种限制太严格,不适合特定的问题,于是C++提供了另外一种形式的访问权限:友元. ...

随机推荐

  1. ActiveMQ初体验(转)

    转载地址:http://www.cnblogs.com/diorlv/p/3328712.html 做了修改 首先介绍下MQ,MQ英文名MessageQueue,中文名也就是大家用的消息队列,干嘛用的 ...

  2. Go语言 使用内置Http组件

    package main import ( "net/http" ) func SayHello(w http.ResponseWriter, req *http.Request) ...

  3. CodeChef COUNTARI Arithmetic Progressions(分块 + FFT)

    题目 Source http://vjudge.net/problem/142058 Description Given N integers A1, A2, …. AN, Dexter wants ...

  4. Hbase0.96 MVCC Lock 知识梳理

    HBASE0.96 MVCC 写入的时候 每个Region包含一个Memstore,维护一个MultiVersionConsistencyControl对象 w = mvcc.beginMemstor ...

  5. 解决Win8无法升级.NET Framework 3.5.1 提示错误0x800F0906

    搞了好久,发现了这篇文,很清晰,就引用了过来.http://www.xdowns.com/article/239/Article_3065.html 起因是windows8.1装oracle10g提示 ...

  6. BZOJ1055: [HAOI2008]玩具取名

    ... #include<bits/stdc++.h> using namespace std; int q[255]; char s[205]; char p[]={'W','I','N ...

  7. Java直接(堆外)内存使用详解

    本篇主要讲解如何使用直接内存(堆外内存),并按照下面的步骤进行说明: 相关背景-->读写操作-->关键属性-->读写实践-->扩展-->参考说明 希望对想使用直接内存的朋 ...

  8. js获取浏览器前缀

    <script> var div = null; var _prefix = (function (temp) { var prefix = ["webkit", &q ...

  9. PHP初学习笔记(2015/4/8)

    //echo C('name'); App/Action/IndexAction.class.php文件夹下的 URL模式 //输出URL模式 //echo C('URL_MODEL'),'<b ...

  10. elasticsearch之节点重启

    Elasticsearch节点重启时背后发生的故事有哪些,应该注意哪些配置内容,本篇文章做一个简单的探讨. 节点离开 在elasticsearch集群中,假设NodeA因为种种原因退出集群,在Node ...