Chapter7:类
- 关于this指针
成员函数通过一个名为this的额外的隐式参数来访问调用它的对象。当我们调用一个成员函数时,用请求该函数的对象初始化this。
total.isbn();
//等价于编译器重写为
Sale_data::isbn(&total);
因为this的目的总是指向“这个”对象,所以this是一个常量指针,我们不允许改变this中保存的地址。
例如this的类型是Sale_data* const。但是this需要遵守初始化规则,所以我们不能把this绑定到一个常量对象。也即:我们不能在一个常量对象上调用普通的成员函数。
为了解决这一问题,引入了常量成员函数,即在成员函数之后加const。
常量对象、常量对象的引用或指针都只能调用常量成员函数。
- 类作用域
类作用域的特点是:编译器分两步来处理:首先编译成员的声明,然后才轮到成员函数体。因此,成员函数体可以随意使用类中的其他成员而无须在意这些成员出现的次序。
类型名要特殊处理。在类中,如果成员使用了外层作用域中的某个名字,而该名字代表一种类型,则类不能在之后重新定义该名字。因此:类型名定义应该出现在类的开始处。
typedef double Money;
class Account
{
public:
Money balance() { return bal; }
private:
typedef double Money; //错误:不能重新定义Money
Money bal;
}; typedef double Money;
class Account
{
typedef double Money; //可以
public:
Money balance() { return bal; }
private:
Money bal;
};
类的作者常常需要定义一些辅助函数,比如add、read、print。尽管这些函数定义的操作从概念上来说属于类的接口组成部分,但它们实际上并不属于类的本身。(因为类本身的话,会附加this参数)
istream &read(istream &is, Sale_data &item)
{
;
}
ostream &print(ostream &os, const Sale_data &item)
{
;//print函数不负责换行,一般来说执行输出任务的函数应该尽量减少对格式的控制,由用户代码确定是否换行。
}
- 构造函数
构造函数不能声明为const,当我们创建类的一个const对象时,直到构造函数完成初始化过程,对象才能真正取得“常量”属性。
如果我们的类没有显式地定义构造函数,那么编译器就会为我们隐式地定义一个默认构造函数。
合成的默认构造函数:1)如果存在类内的初始值,用它来初始化成员;2)否则,默认初始化该成员。
对于一个普通的类来说,必须定义它自己的默认构造函数,原因有三
1)编译器只有在发现类不包含任何构造函数的情况下才会替我们生成一个默认构造函数;
2)合成的默认构造函数可能执行错误的操作。回忆之前:在块中定义的内置类型或复合类型的对象被默认初始化,则它们的值将是未定义的。
3)有时候编译器不能为某些类合成默认的构造函数。
=default
我们定义此构造函数的目的仅仅是因为我们既需要其他形式的构造函数,也需要默认的构造函数。
构造函数初始化列表
当某个数据成员被构造函数初始化列表忽略时,它将以与合成默认构造函数相同的方式隐式初始化(在函数体执行之前)。
成员初始化的顺序与它们在类定义中的顺序一致。所以,Best Practice:初始值列表最好与成员声明顺序一致。
C++11委托构造函数
- 类类型转换
我们可以为类定义隐式转换规则。如果构造函数只接受一个实参,则它实际上定义了次类类型的隐式转换机制。切记:只允许一步类类型转换。
使用explicit抑制隐式转换:
explicit只能在类内声明构造函数时使用,在类外部定义时不应该重复。
explicit只能用于直接初始化,不能用于拷贝初始化。
Sale_data item1(null_data);//正确
Sale_data item2=null_data;//错误
explicit可以显式转换
item.combine(Sale_data(null_book));
item.combine(static_cast<Sale_data>(cin))
- 聚合类:可以使用花括号成员初始值列表
所以成员都是public
没有定义构造函数
没有类内初始值
没有基类,没有virtual
- 字面值常量类:
数据类型都是字面值类型的聚合类是字面值常量类,或者符合下述条件的类:
1)数据类型都是字面值类型;
2)至少有一个constexpr构造函数;
3)数据成员:内置类型的初始值必须是常量表达式;类类型初始值必须使用constexpr构造函数;
4)类必须使用默认的析构函数
- 类的静态成员
静态成员函数不与任何对象绑定在一起,即:不能使用this指针,不能声明为const。
当在类外部定义静态成员时,不能重复static关键字;因为不属于对象,所以不是由构造函数中初始化:需要在类的外部定义和初始化每个静态成员。
class Account
{
static double interestRate;
};
double Account::interestRate = ;
当静态成员是const的时候,可以在类内提供初始值。此时,也应该在类外定义一下该成员。
class Account
{
static constexpr double interestRate = 0.8;
};
constexpr double Account::interestRate;
静态成员可以是不完全类型;可以做默认实参。非静态成员不能做默认实参,因为它值本身是对象的一部分,所以无法真正提供一个对象以便从中获取成员的值。
- 友元
如果类想把一个函数作为它的友元,只需要增加一条以friend关键字开始的函数声明即可。
友元的声明仅仅是指定了访问权限,而非一个通常意义上的函数声明。如果希望调用某个友元函数,那么必须在友元声明之外再专门对函数进行一次声明。
(许多编译器并未强制限定友元函数必须在使用之前在类的外部声明)
令成员函数为友元
需要仔细组织程序结构以满足声明和定义的彼此依赖关系。
class Window_mgr
{
public:
void clear(); };
class Screen
{
//不同于普通函数,之前必须声明
friend void Window_mgr::clear();
}; //Screen定义后,再定义clear函数,因为要用到Screen
void Window_mgr::clear()
{
Screen s;
}
类和非成员函数的声明不是必须在它们的友元声明之前。当一个名字第一次出现在一个友元声明中时,我们隐式地假定该名字在当前作用域中可见。
class X
{
public:
friend void f() {/*定义f*/; }
X() { f(); }//错误,f还没有声明
void g();
}; void X::g() { f(); }//错误,f还没有声明
void f();//声明那个定义在X中的函数
void X::g() { f(); }//正确
类的声明
在声明之后定义之前,类是一个不完全类型。只能在有限情况下使用:
1)可以定义指向这种类型的引用或指针;2)可以声明(但不能定义)以不完全类型作为参数或者返回类型的函数。
Chapter7:类的更多相关文章
- Chapter7(类) --C++Prime笔记
类(关键词):数据抽象(数据成员和函数成员),封装(private),构造函数,静态成员 1.判断一个类是否是抽象数据类型,可以看我们对这个类的操作是对你内的数据成员操作,自己编写相应的处理函数,还是 ...
- Java类的继承与多态特性-入门笔记
相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...
- ###《Effective STL》--Chapter7
点击查看Evernote原文. #@author: gr #@date: 2014-08-31 #@email: forgerui@gmail.com Chapter7 在程序中使用STL Topic ...
- (六)《Java编程思想》——初始化及类的加载顺序
package chapter7; /** * 初始化及类的加载顺序:顺序如下 * 1.基类的static变量 * 2.导出类的static变量 * 3.基类的变量 * 4.基类的构造函数 * 5.导 ...
- 开涛spring3(7.2) - 对JDBC的支持 之 7.2 JDBC模板类
7.2 JDBC模板类 7.2.1 概述 Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDB ...
- python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性
先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,. __getattr__:当在类中找不到attribute的时候 ...
- (转)JDBC模板类。
Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式. JdbcTempl ...
- spring3:对JDBC的支持 之 JDBC模板类
7.2 JDBC模板类 7.2.1 概述 Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDB ...
- synchronized的对象锁和类锁
概念 synchronized 是 Java 中的关键字,是利用锁的机制来实现同步的. 锁机制有如下两种特性: 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制, ...
随机推荐
- 乙醇脱氢酶力场文件的处理(含ZN,NAD,乙醇)
很多蛋白质在行驶生物催化反应(如ATP水解,氨基酸的乙酰化,CoA的去乙酰化,甲基化等等)都需要金属离子(Mg,Zn,Ca等等)的参与,换句话说,金属离子对蛋白功能是必须的.模拟金属酶体系,现在也是分 ...
- org.opencv.android.JavaCameraView 摄像机方向的问题
——> org.opencv.android.JavaCameraView 摄像机方向的问题 ref: http://www.tuicool.com/articles/q6vUvqB 注意:一般 ...
- oracle数据库sql的基本使用
整理了下关于oracle数据库中SQL的基本使用语句,整理如下,方便记忆. oracle的基本术语 数据字典,数据库元数据信息的数据字典表和用户可以读取的数据字典视图组成.存放oracle数据库所用的 ...
- Java 全角字符转半角字符
1.java代码里有时候会遇到代码注入的安全问题,为了防止这种问题,增加了一个过滤功能.主要是过滤全角字符,把url不能识别的全角字符转换成半角字符 public class Test { publi ...
- Spring Transaction + MyBatis SqlSession事务管理机制[marked]
- 上海二手房8月排名:链家、悟空找房、中原、太平洋、我爱我家、易居、房天下、iwjw、房多多、房好多、q房网、、、
房产网站总结 链家: 悟空找房: 中原: 太平洋: 我爱我家: 易居: 房天下: iwjw:有较多二手房信息 链家称王 房多多领跑电商平台 近日,云房数据公布了8月上海房产中介成交数据,从排行榜来看, ...
- poj1961Period(next数组)
http://poj.org/problem?id=1961 对于next数组只能说略懂,其中精髓还是未完全领会 大体是本串相同前缀与后缀的最大长度,读不懂?看串abcdab 这里所说前缀与后缀都为a ...
- JS function的定义方法,及function对象的理解。
废话篇: 今天看到了Function的内容,各种晕,各种混淆有木有.简直是挑战个人脑经急转弯的极限啊.不过,最终这一难题还是被我攻克了,哇咔咔.现在就把这东西记下来,免得到时候又忘了就悲催了.... ...
- pandas.Panel数据
from pandas import Panel, DataFrame import numpy as np dd = {} for i in range(1, 3): name = 'X' + st ...
- [转] gc tips(1)
所有应用软件都需要管理内存,一个应用软件的内存管理系统包括了如下准则:什么时候派发内存,要派发多少内存,什么时候把东西放到回收站,以及什么时候清空回收站.MMgc是Flash Player几乎所有内存 ...