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数据成员作默认实参,将无法提供对象以获取该成员的值,因而是错误的。

转载于:https://www.cnblogs.com/wangfengju/p/6173016.html

C++ Primer 有感(类)相关推荐

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

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

  2. 【C++ Primer】类的多态

    一,概述 1)接口的多种不同的实现方式即为多态. 2)多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作.简单的说, ...

  3. C++ Primer 有感(new和delete表达式)

    定义变量时,必须指定其数据类型和名字.而动态创建对象时,只需指定其数据类型,而不必为该对象命名.取而代之的是,new表达式返回指向性创建的指针. 1.动态创建对象的默认初始化 对于类类型的对象,用该类 ...

  4. C++ Primer 有感(重载操作符)

    1.用于内置类型的操作符,其含义不能改变.也不能为任何内置类型定义额外的新的操作符.(重载操作符必须具有至少一个类类型或枚举类型的操作数.这条规则强制重载操作符不能重新定义用于内置类型对象的操作符的含 ...

  5. [学习笔记]c#Primer中文版-类设计、static成员、const和readonly数据成员

    类的构成:公开操作和属性:非公开实现细节.         类的设计:1.确定类能执行的操作集,这些操作将成为类的成员函数.                             2.确定每个成员函 ...

  6. [c++primer][12]类

    12.1 类的定义和声明 概述 类是将数据与操作封装的抽象数据类型. 访问标号:public,可被使用该类型的所有代码访问:private,可被类成员访问:protected:,受保护成员 成员函数 ...

  7. 【转载】c++之类的基本操作(c++ primer 的读书笔记 ,类对象, 类用户, 类成员的含义)

    一前言 看c++ primer有一个地方看的云里雾里的,这么一段话 可以认为 protected 访问标号是 private 和 public 的混合: • 像 private 成员一样,protec ...

  8. java的格式控制符_C语言的格式控制符

    1.         格式控制符 格式输出printf 作用是向终端输出若干个类型任意的数据. 格式:printf (格式控制符,输出列表) 1)         格式控制符 l          % ...

  9. java 独木桥_趣味算法——青蛙过河(JAVA)

    青蛙过河是一个非常有趣的智力游戏,其大意如下: 一条河之间有若干个石块间隔,有两队青蛙在过河,每队有3只青蛙,这些青蛙只能向前移动,不能向后移动,且一次只能有一只青蛙向前移动.在移动过程中,青蛙可以向 ...

最新文章

  1. MPB:林科院袁志林组-​栎类外生菌根形态学特征描述
  2. vim和NERD树扩展 - 添加文件
  3. formdata上传文件_大文件分片断点上传实现思路以及方案
  4. Java代码03-打印一个菱形
  5. CGImageRef 图片压缩 裁减
  6. LeetCode 594. Longest Harmonious Subsequence
  7. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法
  8. I2C和Modbus通信
  9. 如何将XML文件导入Excel中
  10. 所有的胜利,与征服自己的胜利比起来,都是微不足道。
  11. python异步爬虫_Python实现基于协程的异步爬虫
  12. 原型 继承 原型链 闭包
  13. 2012 国庆中秋黄金周流水帐
  14. matlab如何求距平,matlab编程语句
  15. 高等代数——大学高等代数课程创新教材(丘维声)——2.1笔记+习题
  16. python项目需求文档模板_Python+docxtpl+plotly实现模板word文档图表生成
  17. Markdown实用小技巧: 个个用着都很爽
  18. 百度人脸识别申请授权文件步骤要领
  19. 老男孩教育侵权之后使出了八大“绝招“,撒谎水平爆炸!真相在这里!
  20. RFC5731 - 中文翻译(原创)

热门文章

  1. 为什么我不再推荐使用 MVC 框架?
  2. Git关于pull,commit,push的总结
  3. Spring Cloud构建微服务架构:服务消费(基础)【Dalston版】
  4. JVM:常用调优命令
  5. 【Python】青少年蓝桥杯_每日一题_8.01_随机五角星
  6. android批量删除图片,Android RecyclerView单点、批量数据元素项目item的增加、删除和移动...
  7. 怎么切换用户_走进通信:4G手机跟基站是怎么“交流”的
  8. mqtt linux 编译,MQTT客户端代码X64位Ubuntu环境编译+测试实践小结
  9. W ndoWs7重启按F11没用,windows7无法正常启动按F8也没有效果的解决方法
  10. 成功解决ValueError: Shape of passed values is (33, 1), indices imply (33, 2)