一、成员对象和封闭类

(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(,,);
return ;
}

上例中,如果 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 ;
}

输出结果:

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 ;
}

输出结果:

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()
{ }
};
int main() {
cout << sizeof(CDemo) << endl;
return ;
}

输出结果:


《新标准C++程序设计》3.6-3.7(C++学习笔记9)的更多相关文章

  1. 《新标准C++程序设计》4.5(C++学习笔记15)

    实例:长度可变的整型数组类 int main() { //要编写可变长整型数组类,使之能如下使用: CArray a; //开始里的数组是空的 ; i < ; ++i) a.push_back( ...

  2. 《新标准C++程序设计》4.6(C++学习笔记16)

    重载流插入运算符和流提取运算符 流插入运算符:“<<” 流提取运算符:“>>” cout 是在 iostream 中定义的,ostream 类的对象. “<<” 能 ...

  3. 《新标准C++程序设计》4.4(C++学习笔记14)

    运算符重载为友元函数 一般情况下,将运算符重载为类的成员函数,是较好的选择. 但有时,重载为成员函数不能满足使用要求,重载为普通函数,又不能访问类的私有成员,所以需要将运算符重载为友元. class ...

  4. 《新标准C++程序设计》4.1(C++学习笔记12)

    运算符重载的概念和原理 一.运算符重载的需求 C++预定义的“+.-. * ./.%. ^ .&.~.!.|. = .<< >>.!= ”等运算符,只能用于基本数据类型 ...

  5. 《新标准C++程序设计》3.8(C++学习笔记10)

    友元 友元分为友元函数和友元类两种. 一.友元函数 在定义一个类的时候,可以把一些函数(包括全局函数和其它类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对 ...

  6. 《新标准C++程序设计》3.5(C++学习笔记8)

    常量对象和常量成员函数 一.常量对象 如果希望某个对象的值初始化后就再也不被改变,则定义该对象时可以在前面加const关键字,使之成为常量对象. class CDemo { private: int ...

  7. 正确处理类的复合关系------新标准c++程序设计

    假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是 ...

  8. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  9. 多态实现的原理------新标准c++程序设计

    “多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...

  10. 多态的作用-游戏编程展示------新标准c++程序设计

    游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...

随机推荐

  1. Solr与tomcat搭建(搭建好)

    https://pan.baidu.com/s/1kXagNYJ  密码:hgxd

  2. C# 中[DllImport("user32.dll")]和extern用法和示例----转载

    原文:https://blog.csdn.net/michellehsiao/article/details/7629746         extern 修饰符用于声明在外部实现的方法.extern ...

  3. Django的urls(路由)

    目录 Django的urls(路由) 正则表达式详解 路由匹配(分组匹配) 无名分组 有名分组 反向解析 无名分组反向解析 有名分组反向解析 路由分发 名称空间 虚拟环境 伪静态 Django的url ...

  4. Python字符串(一)

    一.get char 1.获取单个字符 字符串中的每一个字符都会对应一个唯一的下标(索引)用来表示字符串中的位置.下标从0开始依次增加:0对应的是第一个字符:也可以从从-1开始依次减小,-1代表最后一 ...

  5. dir815_FW_102.bin路由器固件解压碰到的坑

    在跟随大神kczwa1进行路由器漏洞分析时,对dir815_FW_102.bin 固件文件用binwalk -e dir815_FW_102.bin命令进行解压时,在根目录squashfs-root下 ...

  6. Vue二次精度随笔(2)

    1.vue中数组更新是否会引起视图刷新的研究 (1)vue中修改数组可以引起视图刷新的方法 (2)不会引起数组刷新的方法,需要手动进行赋值 (3)有些数组的变化是不能够引起视图的刷新的,一个是修改数组 ...

  7. Day 1:思考

    干游戏这行从实习到工作算起来也有快7年的时间了, 7年的时间~上学了.毕业了.工作了.结婚了.孩子要出生了~ 也算是经历了不少的事情了,自己觉得生活过的是越来越好了, 自己做过的游戏也不算少了,不过真 ...

  8. 1.URLConnection

    //爬虫://1.请求到某个网站去//2.返回一些HTML代码//3.从HTML代码提取你想要的信息 HTML解析//4.如果这些HTML中又有你感兴趣的内容//5.递归爬取//准备好网址 URL u ...

  9. Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)

    最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...

  10. 2017 青岛现场赛 I The Squared Mosquito Coil

    Lusrica designs a mosquito coil in a board with n × n grids. The mosquito coil is a series of consec ...