《新标准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(,,);
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)的更多相关文章
- 《新标准C++程序设计》4.5(C++学习笔记15)
实例:长度可变的整型数组类 int main() { //要编写可变长整型数组类,使之能如下使用: CArray a; //开始里的数组是空的 ; i < ; ++i) a.push_back( ...
- 《新标准C++程序设计》4.6(C++学习笔记16)
重载流插入运算符和流提取运算符 流插入运算符:“<<” 流提取运算符:“>>” cout 是在 iostream 中定义的,ostream 类的对象. “<<” 能 ...
- 《新标准C++程序设计》4.4(C++学习笔记14)
运算符重载为友元函数 一般情况下,将运算符重载为类的成员函数,是较好的选择. 但有时,重载为成员函数不能满足使用要求,重载为普通函数,又不能访问类的私有成员,所以需要将运算符重载为友元. class ...
- 《新标准C++程序设计》4.1(C++学习笔记12)
运算符重载的概念和原理 一.运算符重载的需求 C++预定义的“+.-. * ./.%. ^ .&.~.!.|. = .<< >>.!= ”等运算符,只能用于基本数据类型 ...
- 《新标准C++程序设计》3.8(C++学习笔记10)
友元 友元分为友元函数和友元类两种. 一.友元函数 在定义一个类的时候,可以把一些函数(包括全局函数和其它类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对 ...
- 《新标准C++程序设计》3.5(C++学习笔记8)
常量对象和常量成员函数 一.常量对象 如果希望某个对象的值初始化后就再也不被改变,则定义该对象时可以在前面加const关键字,使之成为常量对象. class CDemo { private: int ...
- 正确处理类的复合关系------新标准c++程序设计
假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是 ...
- 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...
- 多态实现的原理------新标准c++程序设计
“多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定.例子: #include<iostream> using namespac ...
- 多态的作用-游戏编程展示------新标准c++程序设计
游戏软件的开发最能体现面向对象设计方法的优势.游戏中的人物.道具.建筑物.场景等都是很直观的对象,游戏运行的过程就是这些对象相互作用的过程.每个对象都有自己的属性和方法,不同对象也可能有共同的属性和方 ...
随机推荐
- C++11并发编程4------线程间共享数据
举个例子: 刚参加工作的你,只能租房住,嫌房租贵就和别人合租了,两个人住一起只有一个洗手间,每天早上起床的时候,如果你室友在洗手间,你就只能等着,如果你强行进去,那画面就不可描述了.同样的问题,如果多 ...
- Java基于redis实现分布式锁(SpringBoot)
前言 分布式锁,其实原理是就是多台机器,去争抢一个资源,谁争抢成功,那么谁就持有了这把锁,然后去执行后续的业务逻辑,执行完毕后,把锁释放掉. 可以通过多种途径实现分布式锁,例如利用数据库(mysql等 ...
- 插入和查询HBase速度都比较慢
表层问题:插入和查询HBase速度比较慢 排查一,查看HBase节点状态,发现正常运行: 排查二,查看访问HBase服务的状态,发现服务停止: 依次点击服务实例,查看服务状态 133和135节点上的服 ...
- 在vnware中配置好redis后,不能使用图形化工具打开
1.先检查防火墙的状态 通过systemctl status firewalld查看firewalld状态,发现当前是dead状态,即防火墙未开启 通过systemctl start firewall ...
- SpringMVC--文件上传与下载
http://blog.csdn.net/u012706811/article/details/51059419
- pycharm连接mysql数据库的时区问题.
登录到mysql的控制台, 执行: set global time_zone='+8:00'; 这设置的是全局时区,重启后失效. 自MySQL 8.0 GA版本开始支持将参数写入并且持久化: set ...
- Springboot项目的接口防刷(实例)
技术要点:springboot的基本知识,redis基本操作, 首先是写一个注解类: import java.lang.annotation.Retention; import java.lang.a ...
- 098、Java中String类之charAt()方法
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- django的save方法被调用时数据是如何被保存的
发送一个django.db.models.signals.pre_save信号,以允许监听该信号的函数完成一些自定义操作. 预处理数据.如果需要,对对象的每个字断进行自动转换. 准备数据库数据.要求咩 ...
- 装系统:Win7,机子是Dell 5460,有半高的mSATA SSD
问题描述:Dell Vostro 5460有一个机械盘,有一个半高的mSATA SSD,现在想将系统重装到mSATA SSD上,但是机子BIOS的Boot选项没有mSATA,只有机械盘,怎么办? 解决 ...