• 《新标准C++程序设计》3.6-3.7(C++学习笔记9)


    一、成员对象和封闭类

    (1)定义

    一个类的成员变量如果是另一个类的对象,就称之为“成员对象”。

    包含成员对象的类叫封闭类。

    (2)封闭类构造函数的初始化列表

    在构造函数中添加初始化列表的写法:

    类名::构造函数名(参数表):成员变量1(参数表),成员变量2(参数表),···

    {

          ···

    }

    “:”和“{”之间的部分就是初始化列表。初始化列表中的成员变量既可以是成员对象,也可以是基本类型的成员变量。

    class CTyre //轮胎类
    {
    private:
    int radius; //半径
    int width; //宽度
    public:
    CTyre(int r,int w):radius(r),width(w) { }
    };
    class CEngine //引擎类
    {
    };
    class CCar { //汽车类
    private:
    int price; //价格
    CTyre tyre;
    CEngine engine;
    public:
    CCar(int p,int tr,int tw );
    };
    CCar::CCar(int p,int tr,int w):price(p),tyre(tr, w)
    {
    };
    int main()
    {
    CCar car(20000,17,225);
    return 0;
    }

    上例中,如果 CCar类不定义构造函数, 则下面的语句会编译出错:CCar car;

    因为编译器不明白 car.tyre该如何初始化。CTyre类中的构造函数有参而默认构造函数无参。

    car.engine 的初始化没问题,用默认构造函数即可。

    任何生成封闭类对象的语句,都要让编译器明白,对象中的成员对象,是如何初始化的。具体的做法就是:通过封闭类的构造函数的初始化列表。成员对象初始化列表中的参数可以是任意复杂的表达式,可以包括函数,变量 ,只要表达式中的函数或变量有定义就行。

    (3)封闭类构造函数和析构函数的执行顺序

    封闭类对象生成时,先执行所有对象成员的构造函数,然后才执行封闭类的构造函数。

    对象成员的构造函数调用次序和对象成员在类中的说明次序一致,与它们在成员初始化列表中出现的次序无关。

    当封闭类的对象消亡时,先执行封闭类的析构函数,然后再执行成员对象的析构函数。次序和构造函数的调用次序相反。

    class CTyre {
    public:
    CTyre() { cout << "CTyre contructor" << endl; }
    ~CTyre() { cout << "CTyre destructor" << endl; }
    };
    class CEngine {
    public:
    CEngine() { cout << "CEngine contructor" << endl; }
    ~CEngine() { cout << "CEngine destructor" << endl; }
    };
    class CCar {
    private:
    CEngine engine;
    CTyre tyre;
    public:
    CCar( ) { cout << “CCar contructor” << endl; }
    ~CCar() { cout << "CCar destructor" << endl; }
    };
    int main(){
    CCar car;
    return 0;
    }

    输出结果:

    CEngine contructor
    CTyre contructor
    CCar contructor
    CCar destructor
    CTyre destructor
    CEngine destructor

    (4)封闭类的复制构造函数

    封闭类的对象,如果是用默认复制构造函数初始化的,那么它里面包含的成员对象,也会用复制构造函数初始化。

    class A
    {
    public:
    A() { cout << "default" << endl; }
    A(A & a) { cout << "copy" << endl;}
    };
    class B { A a; };
    int main()
    {
    B b1,b2(b1);
    return 0;
    }

    输出结果:

    default
    copy

    说明b2.a是用类A的复制构造函数初始化的。而且调用复制构造函数时的实参就是b1.a。

    二、const成员和引用成员

    类还可以有常量型成员变量和引用型成员变量。这两种类型的成员变量必须在构造函数的初始化列表中进行初始化。常量型成员变量的值一旦被初始化,就不能再改变。

    #include<iostream>
    using namespace std;
    int f;
    class CDemo {
    private:
        const int num;//常量型成员变量
        int& ref;     //引用型成员变量
        int value;
    public:
        CDemo(int n) :num(n), ref(f), value(4)
        {
    
        }
    };
    int main() {
        cout << sizeof(CDemo) << endl;
        return 0;
    }

    输出结果:

    12
  • 相关阅读:
    Keras的安装与配置
    Hive实际应用小结
    SparkMLlib-----GMM算法
    ---------菜单目录---------
    Linux(Centos)下使用Docker安装 Portainer-ce(HTTPS支持,docker容器管理软件)
    Linux(Centos)下 docker-ce安装配置(TLS认证)、docker-compose安装与配置
    Centos8 安装进不了图形化安装界面,光标一直在闪解决方案
    开源镜像库
    vue模板项目 推荐项目 vue-element-admin
    Linux 服务器 网卡 流量统计 监控 (vnstat)最新版本安装使用
  • 原文地址:https://www.cnblogs.com/cyn522/p/12273599.html
Copyright © 2020-2023  润新知