一:基本内容

1 类

数据成员:用于存储与类对象相关联的状态

成员函数:对数据成员进行操作

类将接口与实现分离,接口指定了类支持的操作,操作的具体实现细节是类的设计者才需要了解

2 类成员

类成员可以是数据(数据成员)、函数(成员函数)、类型别名

数据成员:类不能具有自身类型的数据成员,但是可以使指向自身类型的指针或引用

成员函数:在类内部定义的成员函数默认为内联inline函数,成员函数的内联可以在声明处也可以在定义处指出

     const成员函数不能改变其所操作的对象的数据成员,const成员函数的const必须同时出现在声明和定义中

3 数据抽象和封装

数据抽象依赖于接口与实现相分离的编程技术,使用者只需抽象的考虑对象执行的类操作,无需关心如何实现

类是一个封装实体,类类型隐藏了类的多数成员

访问标号来定义类的抽象接口和实施封装

4 数据成员重载

struct A
{
int a;
}; struct B : A
{
int a;
}; struct B x;
cout << &x << endl;
cout <<&x.a << endl; struct A *pa = &x;
struct B *pb = &x;
cout << &(pa->a) << endl;
cout << &(pb->a) << endl;

结果:

0x7fffc2c00b40  x对象的起始地址

0x7fffc2c00b44  x对象中x.a的地址,可见前面有一个A::a

0x7fffc2c00b40  说明静态绑定,pa的静态类型是A,所以pa->a是A::a

0x7fffc2c00b44  说明静态绑定,pb的静态类型是B,所以pb->a是B::a

普通的数据成员重载,会在派生类中形成两个同名的成员(其实没有重载,而是正常继承了基类的成员,同时正常产生自己的成员,只不过两个成员的名字相同而已)

5 成员函数重载

通过在派生类中重新定义基类函数,派生类可以覆盖、替换掉基类的函数定义

这种覆盖是动态还是静态,取决于成员函数是否被声明为虚函数

class A
{
public:
int a;
virtual void func(){cout << "a ";cout << a << endl;}
}; class B : public A
{
public:
int a;
void func()
{
cout << a << endl;
A::func();
}
}; int main()
{
B b;
b.a = ;
b.A::a = ;
b.func();
b.A::func();
}

执行结果:

2

a 3

a 3

子类中的数据成员无论是否与父类中的数据成员同名,父类的数据都会被正常继承

如果子类重载了父类的成员函数,则会发生覆盖,但是仍然可以通过 父类名::成员函数名 的方式在子类中调用父类成员函数,同时由于数据成员会正常继承下来,所以用子类对象调用父类成员函数时,子类对象中的数据包含了父类的数据成员,成员函数中访问的变量会使用子类中继承下来的变量,无论变量名是否与子类中的相同 

除了虚函数,其他函数和数据都是静态绑定!!

b.A::func()中的func函数含有一个隐含的this指针 A *const,所以this->a将发生静态绑定,将调用实例b中的基类部分的数据a

基于const的重载:可以理解为const成员函数的隐藏this指针类型为 const A *const,非const成员函数的隐藏this指针类型为A *const,形参不同,实现函数重载

6 可变数据成员

即使在const成员函数中,仍然可以被改变的数据成员,需要被声明为mutable成员

二:构造函数

1 初始化列表

构造函数的初始化列表以冒号开始,就算没有显示执行初始化列表,在构造函数函数体执行之前,还是会以默认的方式初始化成员(按照变量声明的顺序)

所以初始化列表可以理解为并不是执行初始化,而是为数据成员初始化提供了一种选择。所以没有默认构造函数的成员一定要在初始化列表中

默认初始化中,内置类型的成员的初始值取决于类对象的作用域,局部作用域中不被初始化,全局作用域中被初始化为0

成员初始化的顺序按照定义的顺序,而不是按照初始化列表中的顺序,这点可能造成程序出错:

class X{
int i;
int j;
public:
X(int val):j(val),i(j){}
};

先初始化i,但初始化列表中i依赖于j,所以i最终初始化的值可能并非我们想要的值(这里如果X对象实例是局部变量,i的值将随机,X若是全局变量,i的值为0)

初始化列表中,可以向数据成员传递满足数据成员类型的构造函数的各种形式的形参

2 默认构造函数

一个类如果定义了自己的构造函数,编译器将不会合成默认的构造函数

需要注意的是,如果一个类A的数据成员中有另一个没有默认构造函数的类B,那么编译器不会为A合成默认构造函数

具有默认构造函数的类A的对象,不能用 A a()进行定义,而是 A a

3 每个构造函数都定义了一个隐式转换

explicit声明的构造函数,可以抑制由构造函数定义的隐式转换,explicit只用于类构造函数的声明中,类外部定义的构造函数,不需要也不能加上explicit限定

三 其他

1 友元函数

友元机制允许一个类将 对其非公有成员的访问权 授予指定的函数或类

友元声明只能出现在类定义的内部,通常将友元成组的放在类定义的开始或结尾是个好主意

2 static数据成员

对特定类类型的全体对象而言,有时候需要访问一个全局对象,但是全局对象会破坏封装(一般的用户代码就可以修改这个全局对象),类的static数据成员独立于该类的任意对象而存在,该数据成员与类相关联,而不是与对象相关联

static数据成员必须在全局范围内进行初始化 使用 type classname::x的形式,此时不能指定static限定

static const成员和const static成员,只有int类型可以在类内部初始化,其他任何类型都要在外部全局范围内进行初始化,不能在初始化列表上

static const int既可以在类内部初始化,又可以在外部全局进行初始化,但只能初始化一次

static成员既可以用A::来调用,又可以用a.来调用

无论是public还是private,static数据正常遵循上面的初始化规则,同时正常遵循public、private的权限设定

3 static成员函数

static成员函数没有this指针,可以直接访问所属类的static成员,但是不能访问类的非static成员

static成员函数不能被声明为const(const函数说明函数不修改调用对象的数据,static成员本身就不会访问对象的数据)

static成员函数不能被声明为虚函数

c++ primer复习(五):类的更多相关文章

  1. C++ 11 从C++ primer第五版的学习笔记

    1. auto (page107) auto 推断会忽略const   const int ci = i, & cr = ci; auto b = ci; // b is an int (to ...

  2. javascript函数一共可分为五类: ·常规函数 ·数组函数 ·日期函数 ·数学函数 ·字符串函数

    javascript函数一共可分为五类:    ·常规函数    ·数组函数    ·日期函数    ·数学函数    ·字符串函数    1.常规函数    javascript常规函数包括以下9个 ...

  3. 实验楼课程管理程序-深入学习《C++ Primer第五版》实验报告&学习笔记1

    本片博客为实验楼的训练营课程深入学习<C++ Primer第五版>的实验报告和学习笔记. 原课程地址为:https://www.shiyanlou.com/courses/405# 原文出 ...

  4. IP分为五类

    IP地址分为五类: IP地址分为五类:A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验. 常用的三类IP地址 IP = 网路地址(网络号)+主机地址(主 ...

  5. 最常用的五类CSS选择器

    一些新手朋友对选择器一知半解,不知道在什么情况下运用什么样的选择器,这是一个比较头疼的问题,针对新手朋友,对CSS选择器作一些简单的说明,希望能对大家的学习工作有一定的帮助,更多的CSS知识请参考We ...

  6. IP分类:A,B,C,D,E五类

    IP地址分为五类: IP地址分为五类:A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验. 常用的三类IP地址 IP = 网路地址(网络号)+主机地址(主 ...

  7. C++PRIMER第五版练习题答案第一章

    C++PRIMER第五版练习题答案第一章 应该有很多小伙伴和我一样,闲来无事买了本C++的书自己啃,课后的练习题做的很揪心,这里我分享下我写的答案,希望能帮助到你,提供源码,就不跑了哈,毕竟现在是第一 ...

  8. C++Primer第五版学习笔记

    <C++ Primer>Learning Note 程序实例下载地址:http://www.informit.com/title/0321714113 第一章            开始 ...

  9. C Primer Plus--C存储类、链接和内存管理之存储类(storage class)

    目录 存储类 作用域 链接 存储时期 自动变量 寄存器变量 具有代码块作用域的静态变量 具有外部链接的静态变量 extern关键字 具有内部链接的静态变量 多文件 存储类 C为变量提供了5种不同的存储 ...

随机推荐

  1. JavaScript删除数组重复元素的5个高效算法

    之前一段时间一直在准备面试, 因而博客太久没更新: 现在基本知识点都复习完毕, 接下来就分享下 面试的一些常见问题: 去正规的互联网公司笔试.面试有很大的概率会碰到 使用javascript实现数组去 ...

  2. A Tour of Go If

    The if statement looks as it does in C or Java, except that the ( ) are gone and the { } are require ...

  3. python 实战

    用Python写一个真正的Web App! 目标 我们设定的实战目标是一个Blog网站,包含日志.用户和评论3大部分. 比如webpy.org上就提供了一个Blog的例子,目测也就100行代码. 我们 ...

  4. Grails教程之--我的理解

    最近工作中接触到了Grails,对于这门技术,网上的资料不算太多,有的基本也是大同小异.我打算边学边写一些东西,毕竟是一个学习的过程,写的东西如果有错误或者理解不正确的地方,还希望大家能指出来.帮助我 ...

  5. [转]freemaker格式化日期

    转至:http://wentao365.iteye.com/blog/2047234 1.格式化日期 ${updated?string("yyyy-MM-dd HH:mm:ss") ...

  6. T-SQL语句查看作业等信息

    因服务器需要迁移,需要将现有JOB迁移至新服务器,待服务器调整完毕,则重新迁移到原服务器,所以在做迁移之前希望将现有JOB进行备份,不至于乱了执行时间.1.查看所有作业列表USE master SEL ...

  7. C# .Net基础知识点解答

    原文地址 1. 什么是.NET?什么是CLI?什么是CLR?IL是什么?JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式? 通俗的讲,.Net是微软开发应用程序的一个平台: CLI是C ...

  8. Hadoop与分布式开发

        hadoop上的并行应用程序开发是基于MapReduce编程框架的,MapReduce编程模型的原理是:利用一个输入的key/value对集合来产生一个输出的key/value对集合. Map ...

  9. 解决windows server 2003不认U盘或移动硬盘

    解决windows server 2003不认U盘或移动硬盘1.进入命令提示符环境(也就是DOS) 2.进入DISKPART程序 3.输入AUTOMOUNT ENABLE指令 4.OK,下次USB硬盘 ...

  10. leecode 每日解题思路 64 Minimum Path Sum

    题目描述: 题目链接:64 Minimum Path Sum 问题是要求在一个全为正整数的 m X n 的矩阵中, 取一条从左上为起点, 走到右下为重点的路径, (前进方向只能向左或者向右),求一条所 ...