构造&析构函数

  构造函数

    定义:与类同名,可以有参可以无参,主要功能用于在类的对象创建时定义初始化的状态,无返回值,也不能用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. 逻辑回归(Logistic Regression)

    转载请注明出自BYRans博客:http://www.cnblogs.com/BYRans/ 本文主要讲解分类问题中的逻辑回归.逻辑回归是一个二分类问题. 二分类问题 二分类问题是指预测的y值只有两个 ...

  2. linux下bus、devices和platform的基础模型

    转自:http://blog.chinaunix.net/uid-20672257-id-3147337.html 一.kobject的定义:kobject是Linux2.6引入的设备管理机制,在内核 ...

  3. 2.goldengate日常维护命令(转载)

    goldengate日常维护命令 发表于 2013 年 7 月 4 日 由 Asysdba 1.查看进程状态 GGSCI (PONY) 2> info all 2.查看进程详细状态,有助于排错 ...

  4. 【转载】scribe、chukwa、kafka、flume日志系统对比

    原文地址:http://www.ttlsa.com/log-system/scribe-chukwa-kafka-flume-log-system-contrast/ 1. 背景介绍许多公司的平台每天 ...

  5. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  6. 图像分割算法-GraphSeg算法

    图像分割是图像处理中的一个基础课题范围,本文简要介绍一种比较好的图像分割算法: Efficient Graph-Based Image Segmentation 论文出处:http://cs.brow ...

  7. java.lang.OutOfMemoryError: bitmap size exceeds VM budget解决方法

    1 BitmapFactory.decodeFile(imageFile); 用BitmapFactory解码一张图片时,有时会遇到该错误.这往往是由于图片过大造成的.要想正常使用,则需要分配更少的内 ...

  8. 2016"百度之星" - 资格赛(Astar Round1)

    逆元 1001 Problem A 求前缀哈希和逆元 #include <bits/stdc++.h> typedef long long ll; const int MOD = 9973 ...

  9. VBA: Cant find project or librar

    Appears OK to me but the error message " Cant find project or library." suggests it could ...

  10. myeclipse2014

    myeclipse 2014-GA offline  迅雷下载  http://downloads.myeclipseide.com/downloads/products/eworkbench/201 ...