1.在类内部,声明成员函数时必需 的,而定义成员函数则是可选的。在类内部定义的函数默认为inline。

2.const成员函数不能改变其所操作的对象的数据成员。const必须同时出现在声明和定义中,若只出现其中一处,就会出现一个编译时错误。

3.显示指定inline成员函数

在类内部定义的成员函数默认是inline。显示指定inline成员函数的办法有3种:

(1)类定义体内部指定inline,作为其声明的一部分。

(2)类定义体外部的函数定义上inline

(3)类定义体内和外均指定为inline

注意:inline成员函数的定义必须在调用该函数的每个源文件中时可见的。不在类定义体内定义的inline成员函数,其定义通常用放在有类定义的同一头文件中。

4.在一个给定的源文件中,一个类只能被定义一次。如果在多个文件中定义一个类,那么每个文件中的定义必须是完全相同的。

5.在声明之后、定义之前的类是一个不完全的类型。不完全类型只能以有限的方式使用。不能定义该类型的对象。不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型的作为形参类型或者返回类型的函数。

6.定义对象时,将为其分配存储空间,但(一般而言)定义类型时不进行存储分配。

7.在普通的非const成员函数中,this的类型是一个指向类类型的const指针,可以改变this所指向的值,但不能改变this所保存的地址。在const成员函数中,this的类型时一个指向const类类型对象的const指针。既不能改变this所指向的对象,也不能改变this所保存的地址。

8.不能从const成员函数返回指向类对象的普通引用。const成员函数只能返回*this作为一个const引用。

9.如果函数在类定义体之外定义,则用于返回类型的名字在类作用域之外。如果返回类型使用由类定义的类型,则必须使用完全限定名。

例如:

class Screen
{
public:
typedefstd::string::size_type index;
index get_cursor() const;
}; inline Screen::index Screen::get_cursor() const
{
return cursor;
}

该函数的返回类型时index,这是在Screen类内部定义的一个类型名。

10.当成员定义在类定义的外部时,要考虑在成员函数定义之前出现的全局作用域声明。

class Screen
{
public:
// ....
void setHeight(index);
private:
indexheight;
};
Screen::index verify(Screen::index); void Screen::setHeight(index var)
{
height =verify(var);
}

注意:全局函数verify的声明在Screen类定义之前是不可见的。然而名字查找可以考虑那些出现在成员函数定义之前的外围作用域声明,并找到全局函数verify的声明。

11.从概念上讲,可以认为构造函数分两个阶段执行:(1)初始化阶段;(2)普通的计算阶段。计算阶段由构造函数函数体中的语句组成。

不管成员是否在构造函数初始化列表中显示初始化,类类型的数据成员总是在初始化阶段初始化。初始化发生在计算阶段开始之前。

在构造函数初始化列表中没有显示提及的每个成员,使用与初始化变量相同的规则来进行初始化。运行该类型的默认构造函数,来初始化类类型的数据成员。内置或复合类型的成员的初始值依赖于对象的作用域:在局部作用域中这些成员不被初始化,而在全局作用域中他们被初始化为0。

例如:

Sales_item::Sales_item(const string &book)
{
isbn = book;
units_sold = 0;
revenue = 0.0;
}

这个构造函数给类Sales_item的成员赋值,但没有进行显示初始化。不管是否有显示的初始化式,在执行构造函数之前,要初始化isbn成员。这个构造函数隐式使用默认的string构造函数初始化isbn。执行构造函数的函数体时,isbn成员已经有值了。该值被构造函数函数体中的赋值所覆盖。

12.有些成员必须在构造函数初始化列表中进行初始化。对于这样的成员,在构造函数函数体中对它们赋值不起作用。

(1)没有构造函数的类类型的成员。

(2)const 成员。

(3)引用类型的成员。

13.只有当一个类没有定义构造函数时,编译器才会自动生成一个默认构造函数。

14.合成的默认构造函数使用与变量初始化相同的规则来初始化成员。具有类类型的成员通过运行各自的默认构造函数来进行初始化。内置和复合类型的成员,如指针和数组,只对定义在全局作用域中的对象才初始化。当对象定义在局部作用域中时,内置或复合类型的成员不进行初始化。

如果类包含内置或复合类型的成员,则该类不应该依赖于合成的默认构造函数。它应该定义自己的构造函数来初始化这些成员。

15.explicit关键字只能用于类内部的构造函数声明上。在类的定义体外部所做的定义上不再重复它。

通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为explicit。将构造函数设置为explicit可以避免错误,并且当转换有用时,用户可以显示的构造对象。

16.友元机制允许一个类将对其非公有成员的访问权授予指定的函数或类。友元的声明以关键字friend开始。它只能出现在类定义的内部。

17.友元可以是普通的非成员函数,或前面定义的其他类的成员函数,或整个类。将一个类设为友元,友元类的所有成员函数都可以访问授予友元关系的那个类的非公有成员。当我们将成员函数声明为友元时,函数名必须用该函数所属的类名字加以限定。

注意:必须先定义包含成员函数的类,才能将成员函数设为友元。

18.非static数据成员存在于类类型的每个对象中。不像普通的数据成员,static数据成员独立于该类的任意对象而存在;每个static数据成员是与类关联的对象,并不与该类的对象关联。static成员函数没有this形参,它可以直接访问所属类的static成员,但不能直接使用非static成员。

19.可以通过作用域操作符从类直接调用static成员,或者通过对象、引用或指向该类类型对象的指针间接调用。

20.当我们在类的外部定义static成员时,无须重复指定static保留字,该保留字只出现在类定义体内部的声明处。

21.因为static成员不是任何对象的组成部分,所以static成员函数不能被声明为const,毕竟,将成员函数声明为const就是承诺不会修改该函数所属的对象。static成员函数也不能声明为虚函数。

22.static数据成员必须在类定义体的外部定义。不像普通数据成员,static成员不是通过类构造函数进行初始化,而是应该在定义时进行初始化。(保证对象正好定义一次的最好办法,就是将static数据成员的定义放在包含类的非内联成员函数定义的文件中。

定义static数据成员的方式与定义其他类成员和变量的方式相同:先指定类型名,接着是成员的完全限定名。

doubleAccount::interestRate = initRate();

注意,尽管initRate是私有的,我们仍然可以使用该函数来初始化interestRate。像任意的其他成员定义一样,interestRate的定义是在类的作用域中,因此可以访问该类的私有成员。

像使用任意的类成员一样,在类定义体外部引用类的static成员时,必须指定成员是在哪个类中定义的。然而,static关键字只能用于类定义体内部的声明中,定义不能标示为static。

23.特殊的整型const static 成员

一般而言,类的static成员,像普通数据成员一样,不能在类的定义体中初始化。相反,static数据成员通常在定义时才初始化。这个规则的一个例外是,只要初始化是一个常量表达式,整型const static数据成员就可以在类的定义体中进行初始化:

classAccount
{
public:
static double rate()
{
return interestRate;
}
static void rate(double);
private:
static const int period = 30;
double daily_tbl[period];
};

注意:const static 数据成员在类的定义体中初始化时,该数据成员仍必须在类的定义体之外进行定义。在类内部提供初始化式时,成员的定义不必再指定初始值:

const int Account::period;

24.static成员不是类对象的组成部分

static成员独立于任何对象而存在,不是类类型对象的组成部分。

(1)static 数据成员的类型可以是该成员所属的类类型。非static成员被限定声明为其自身类对象的指针或引用:

classBar
{
public:
//....
private:
static Bar mem1;
Bar* mem2;
Bar mem3;
};

(2)static数据成员可用作默认实参:

classScreen
{
public:
Screen& clear(char = bkground);
private:
static const char bkground = '#';
};

非static数据成员不能用作默认实参,因为它的值不能独立于所属的对象而使用。使用非static数据成员作默认实参,将无法提供对象以获取该成员的值,因而是错误的。

C++ Primer 有感(类)的更多相关文章

  1. C++ Primer 有感(管理类的指针成员)

    C++类的指针成员与其他成员有所不同,指针成员指向一个内存地址,该地址的内存需要我没管理. 我现在分析一下为什么要管理指针成员. 有如下Student类,Student.h如下: [cpp] view ...

  2. C++ Primer 有感(命名空间)

    1.命名空间定义以关键字namespace开始,后接命名空间的名字. 2.命名空间可以在全局作用域或其他作用域内部定义,但不能在函数或类内部定义. 3.定义在命名空间中的实体称为命名空间的成员.像任意 ...

  3. C++ Primer 与“类”有关的注意事项总结

    C++ 与"类"有关的注意事项总结(一) 1. 除了静态 static 数据成员外,数据成员不能在类体中被显式地初始化. 例如 : class First { int memi = ...

  4. C++ Primer 有感(异常处理)

    1.异常是通过抛出对象而引发的.该对象的类型决定应该激活哪个处理代码.被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那个. 2.执行throw的时候,不会执行跟在throw后面的语句 ...

  5. C++Primer学习——类

    我们在创建类的对象时,类不应该仅仅被声明,还应该被定义过,否则无法知道类占用了多少的内存 但是如果一个类的名字已经出现过就被认为是已经声明过了,所以允许包含自己的指针或者引用. 默认构造函数: 当类中 ...

  6. C++ Primer 有感(标准库vector及迭代器)

    vector是同一种对象的集合,每个对象都有一个对应的整数索引值.和string对象一样,标准库将负责管理与存储元素相关的类存.引入头文件 #include<vector> 1.vecto ...

  7. C++ Primer 有感(标准库map类型)

    map是键-值对的集合.map类型通常可以理解为关联数组:可以使用键作为下标获取一个值,正如内置数组一样.而关联的本质在于元素的值于某个特定的键相关联,而并非通过元素在数组中的位置获取. 1.map对 ...

  8. C++ Primer 有感(异常处理)(四)

    查看普通函数的声明的时候,不可能知道该函数会抛出什么异常,但是在捕获异常的时候要知道一个函数会抛出什么样的异常,以便捕获异常. 异常说明:指定,如果函数抛出异常,抛出的异常将是包含在该说明中的一种,或 ...

  9. C++ Primer 有感(异常处理)(三)

    先看下面的代码: [cpp] view plaincopy int main() { int *i=new int(10); /* 这中间的代码出现异常 */ delete i; return 0; ...

随机推荐

  1. JavaScript for 循环

    循环可以将代码块执行指定的次数. JavaScript 循环 如果您希望一遍又一遍地运行相同的代码,并且每次的值都不同,那么使用循环是很方便的. 我们可以这样输出数组的值: 一般写法: documen ...

  2. JS——2048(支持触屏及键盘操作)

    <html> <head> <title>2048</title> <style type="text/css"> ta ...

  3. [BBS]搭建开源论坛之Jforum搭配开源CKEDITOR

    本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/47946065 使用默认的编辑器的时候,格式都无法保 ...

  4. rbac 概念

    1 权限管理 1.1 什么是权限管理 分享牛原创,分享牛系列.基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户 ...

  5. [系统运维]Supervisord安装和启动程序

    supervisord 是client/server 系统 把不是守护进程的进程变成守护进程 监控它自己启动的进程,类似于看门狗 可以作为开机启动的一种封装 可以精确控制进程的状态,而不是pidfil ...

  6. Python实现数据库一键导出为Excel表格

    依赖 Python2711 xlwt MySQLdb 数据库相关 连接 获取字段信息 获取数据 Excel基础 workbook sheet 案例 封装 封装之后 测试结果 总结 数据库数据导出为ex ...

  7. 视频特性TI(时间信息)和SI(空间信息)的计算工具:TIandSI-压缩码流版

    ===================================================== TI(时间信息)和SI(空间信息)计算工具文章列表: 视频特性TI(时间信息)和SI(空间信 ...

  8. Hadoop与分布式数据处理 Spark VS Hadoop有哪些异同点?

    Spark是一个开源的通用并行分布式计算框架,由加州大学伯克利分校的AMP实验室开发,支持内存计算.多迭代批量处理.即席查询.流处理和图计算等多种范式.Spark内存计算框架适合各种迭代算法和交互式数 ...

  9. 关于Lt分发系统的时序图分析

    我们已经知道,系统共分为两个模块,mather与son 同时系统允许的操作也有三种,向mather提交war包,我某个服务器更新代码,为所有服务器更新代码 我们一个一个来看 先说,向mather提交w ...

  10. Android项目开发填坑记-so文件引发的攻坚战

    故事的最初 我负责的项目A要求有播放在线视频的功能,当时从别人的聊天记录的一瞥中发现百度有相关的SDK,当时找到的是Baidu-T5Player-SDK-Android-1.4s,项目中Demo的so ...