构造&析构函数

  构造函数

    定义:与类同名,可以有参可以无参,主要功能用于在类的对象创建时定义初始化的状态,无返回值,也不能用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. 将Linux下的Android签名对pk8和pem转换为Eclipse下的签名(keystore)

    一 在github上下载工具 https://github.com/getfatday/keytool-importkeypair 二 将工具在Linux环境下解压或者解压后Copy到Linux下,运 ...

  2. 简单测试flume+kafka+storm的集成

    集成 Flume/kafka/storm 是为了收集日志文件而引入的方法,最终将日志转到storm中进行分析.storm的分析方法见后面文章,这里只讨论集成方法. 以下为具体步骤及测试方法: 1.分别 ...

  3. featherview模板引擎

    1.判断语法 <?php if(isset($value['fromVR']) && !empty($value['fromVR'])) {?> <s class=& ...

  4. Shell 编程基础之 && 与 ||

    一.引言 Shell 在执行某个命令的时候,会返回一个返回值,该返回值保存在 shell 变量 $? 中.当 $? == 0 时,表示执行成功:当 $? == 1 时,表示执行失败.有时候,下一条命令 ...

  5. 最新版 CocoaPods 的安装流程

                                       iOS 最新版 CocoaPods 的安装流程     1.移除现有Ruby默认源 $gem sources --remove h ...

  6. mssql 获取自增列起始及增量

    --首先创建一个表 CREATE TABLE [dbo].[abcd]( ,) NOT NULL, ) NULL, ) NULL ) ON [PRIMARY] --获取起始值 SELECT IDENT ...

  7. ibatis实现Iterate的使用

    <iterate property="" /*可选, 从传入的参数集合中使用属性名去获取值, 这个必须是一个List类型, 否则会出现OutofRangeException, ...

  8. 深入浅出JMS(二)--ActiveMQ简单介绍以及安装

    现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的. 上篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了消息通信的规范JM ...

  9. Android学习笔记之 android:collapseColumns ,android:shrinkColumns 和stretchColumns

    摘自:http://blog.csdn.net/sjf0115/article/details/7213565/ TableLayout是一个使用复杂的布局,最简单的用法就仅仅是拖拉控件做出个界面,但 ...

  10. 学习使用html与css,并尝试写php

    这两天看了一点php,本想着实践一下,发现自己的服务器还没弄好,php的代码只写了两三行嵌在html中,还运行不了,同时还发现自己这几天学的html和css还不够,总是频频出现问题,学习的样式和布局都 ...