`
kofsky
  • 浏览: 201597 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

讨论记录之C++细节

阅读更多

ParticipantsLFHZPCPPZY<!----><o:p></o:p>

Date<!----><st1:chsdate isrocdate="False" month="9" islunardate="False" day="16" w:st="on" year="2008">08-09-16</st1:chsdate>  7:20PM<o:p></o:p>

Recorder: CPPZY<o:p></o:p>

参考文献:<o:p></o:p>

1、《effective C++2nd EditionScott Meyers etc.<o:p></o:p>

2、《C++程序设计教程》,钱能<o:p></o:p>

3、《高质量C++C编程指南》,林锐<o:p></o:p>

4http://keith.ecjtu.com/article.asp?id=319<o:p></o:p>

<o:p> </o:p>应大家的要求,今天晚上开始了我们的第一次讨论会。<o:p></o:p>

主要是针对C++里面的一小撮问题展开的,这里我给出讨论的概要:<o:p></o:p>

1、关于优先级与结合性;(这里要重点“批”一下HZPZY,正号和加号都分不清的家伙)(顶)<o:p></o:p>

2#define \inline\const(顺便涉及到inline virtual的连用问题);<o:p></o:p>

3const的作用(包括修饰类的成员函数,成员函数返回值,成员函数的参数列表,数据成员);<o:p></o:p>

4、重载、覆盖(重写/改写,实现多态)以及隐藏的区别;<o:p></o:p>

5、构造函数和析构函数<o:p></o:p>

       6、关于虚拟函数、虚基类及多继承<o:p></o:p>

1、优先级口诀:(除了标明是右结合外,都是左结合)<o:p></o:p>

括号成员第一;//[]、()<o:p></o:p>

全体单目第二;//比如++--+(正号)、-(负号)、指针运算符* & 右结合<o:p></o:p>

乘除余第三;//取余 左结合<o:p></o:p>

移位五,关系六;<o:p></o:p>

等于不等排第七;<o:p></o:p>

位与亦或和位或;//& ^|<o:p></o:p>

逻辑或跟与;//&&||<o:p></o:p>

条件高于赋值;//注意的是赋值运算符很多,包括= *= /= += -= |= <<=>>=  二者都是右结合<o:p></o:p>

逗号排最后。<o:p></o:p>

上面是C中的规则,而C++由于引入了一些新的运算符,因此,有些出入,如表1

 

<st1:chmetcnv tcsc="0" hasspace="True" sourcevalue="1" numbertype="1" negative="False" unitname="C" w:st="on">1 C</st1:chmetcnv>++ 运算符优先级列表<o:p></o:p>

见两个例子:<o:p></o:p>

(1) int x=1y=0<o:p></o:p>

x&&x+y&&++y<o:p></o:p>

加括号确定优先级的方法
  当多个优先级不同的运算符在一起时,为了不混淆,可以先加上括号,这样就分出层次了,相同层次的考虑结合性问题,当确定下来先算那块时,再往这块里面深入。例如上面的例子,我们可以这样加上括号:从左向右看,由于!比&&优先级高,所以有(!x),又由于&&+优先级低,所以有(x+y),而++优先级高于&&,所以(++y)。这样整个式子就变成了:(!x&&x+y&&++y),最外层的是两个&&运算,由于&&的结合性是从左至右,所以上式可看成:A&&B&&C,先计算A,再计算B,最后算C.由于x=1,则!x就为假,后面的就不需要再算了,整个语句的值为假。执行完后,y的值没变,还是0.
  所以碰到不清楚先算谁后算谁时,先加个括号看看,就明白了先后次序。<o:p></o:p>

(2)给语句c=a>bab;加括号。此语句有三个运算符:=>、? :,应该怎样加括号呢?<o:p></o:p>

 第一种方案:c=((a>b)?ab);
  第二种方案:c=a>bab));
  第三种方案:(c=a>bab);
  应该是那一种呢?按照运算符优先级的高低顺序,>优先级高于=,所以不可能把(c=a)括起来。而>优先级高于? :运算符。所以也不可能把(bab)括起来。因此,第一种答案正确。<o:p></o:p>

<o:p> </o:p>

2、尽量以constinline取代#define<o:p></o:p>

尽量以编译器取代预处理器或许更好,因为#define通常不被视为语言本身的一部分。<o:p></o:p>

#define导致的结果就是程序内所使用的名称并未出现于符号表之中。可以改用常量来声明。<o:p></o:p>

若是需要一个class专属常量,即将这个常量的scope局限于class 之内,必须让它成为一个member,而为了确保这个常量至多只有一份实体,则必须让他成为一个static member,例如:
class GamePlayer{<o:p></o:p>

private:
       static const int NUM;//
仅仅是个声明而非定义<o:p></o:p>

    …<o:p></o:p>

}<o:p></o:p>

必须在类定义文件中定义该类成员:const int GamePlayer::NUM=5;<o:p></o:p>

     另一个误用#define指令的常见例子是,以它来实现宏——看起来像函数,却又不会带来函数调用所需的成本。经典例子就是计算两数的最大值:<o:p></o:p>

#define  max(a,b)  ((a)>(b)?(a) : (b))<o:p></o:p>

即使加上了小括号,还是会发生一个可怕的动作:<o:p></o:p>

int a=5,b=0;<o:p></o:p>

max(++a,b);//a被累加两次<o:p></o:p>

max(++a,b+10);//a被累加一次<o:p></o:p>

这时,我们可以使用inline函数,既可以得到宏带来的高效率以及函数带来的可预期行为和类型检验。例如:<o:p></o:p>

inline int max(int a, int b) {return a>b?a:b; }<o:p></o:p>

这与前述宏并不完全相同,因为这个版本的max只接受int类型参数,不过,template可以修正这一问题,这里by reference相比by value可以获取更高的效率。<o:p></o:p>

template<class T><o:p></o:p>

inline const T& max(const T& a, const T&b)<o:p></o:p>

{return a>b?a:b; }<o:p></o:p>

 

3const的作用<o:p></o:p>

1)修饰类的成员函数时:<o:p></o:p>

即在成员函数声明时将const置于成员函数参数列表后分号前,代表它不能对类的数据成员进行修改,但是有一个例外,就是当数据成员前有mutable修饰时,它是可以被该函数修改的;<o:p></o:p>

2)修饰成员函数返回值及函数参数时:<o:p></o:p>

意即被修饰的量是不可被修改的,前者意味着在成员函数返回后得到的值不可被更改,后者意味着不能在函数体内对参数进行变动,只能读取它;<o:p></o:p>

3)对于类中的const常量,它只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。<o:p></o:p>

     不能在类声明中初始化const数据成员,只能在类构造函数的初始化表中进行,例如:<o:p></o:p>

class A<o:p></o:p>

{…<o:p></o:p>

const int SIZE=100;//错误,企图在类声明中初始化const数据成员<o:p></o:p>

int array[SIZE];//错误,位置的SIZE<o:p></o:p>

};<o:p></o:p>

应该是:<o:p></o:p>

class A <o:p></o:p>

{<o:p></o:p>

A(int size);<o:p></o:p>

const int SIZE;<o:p></o:p>

};<o:p></o:p>

A::A(int size):SIZE(size){<o:p></o:p>

…<o:p></o:p>

}<o:p></o:p>

若要建立在整个类中都恒定的常量,需要用枚举常量来实现,例如:<o:p></o:p>

class A{<o:p></o:p>

       enum{SIZE1=100,SIZE2=200};//<o:p></o:p>

       int array1[SIZE1];<o:p></o:p>

       int array2[SIZE2];<o:p></o:p>

};<o:p></o:p>

枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数.(PI=3.14159)<o:p></o:p>

<o:p> </o:p>

4、重载(overload)、覆盖(override)以及隐藏<o:p></o:p>

本来是讨论多态的,但是我们又讲到了重载这个概念,对于一个类中的成员函数,其被重载的特征:<o:p></o:p>

1)相同的范围(同一个类中);<o:p></o:p>

2)函数名相同,参数列表不同,返回值类型可相同也可不同。<o:p></o:p>

覆盖是指派生类函数覆盖基类函数,其特征:<o:p></o:p>

1)不同范围;<o:p></o:p>

2)函数名字相同,参数列表相同,<o:p></o:p>

3)基类必须要有virtual关键字。<o:p></o:p>

除覆盖外,所有同名的基类函数与子类函数都属于隐藏,下面是一个例子,讲得比较清楚,也点出了问题的本质:<o:p></o:p>

  1. class Base  
  2. {
  3. public:
  4.  Base();
  5.  virtual ~Base();
  6.  public:
  7.  virtual void f(float x)
  8.  {
  9.   cout << "Base f(float)" << x <<endl;
  10.  }
  11.  void g(float x)
  12.  {
  13.   cout<< "Base g(float)" << x <<endl;
  14.  }
  15.  void h(float x)
  16.  {
  17.   cout<< "Base h(float)" << x <<endl;
  18.  }
  19. };
  20. 派生类:
  21. class Derived:public Base
  22. {
  23. public
分享到:
评论

相关推荐

    c++会议记录格式

    在IT行业中,会议记录是团队协作和项目管理中不可或缺的一部分,尤其对于C++开发者或团队而言,有效的会议记录能够确保信息传递的准确性和效率。以下将详细解释如何编写符合标准的C++会议记录,以及其相关知识点。 ...

    C++11最新使用手册

    该文档为 C++11 标准的早期草稿版本,旨在为 C++ 开发者提供全面的更新指南,帮助理解并掌握 C++11 的新特性和改进之处。 #### 三、文档主要内容 - **1. General 一般性介绍** - **1.1 Scope 范围**:定义了 C++...

    c++核心编程指南中文版

    - **版本状态**: 当前版本为0.6版,作为开源项目的一部分,它处于不断发展和完善之中。 - **许可协议**: 该项目采用了MIT许可证,并规定贡献者需签署贡献者许可协议。 - **目标受众**: 面向所有对C++感兴趣的开发者...

    前辈的c++50个建议

    《Effective C++》、《More Effective C++》以及《Exceptional C++》都是经典之作,它们涵盖了大量关于如何写出高效、可维护代码的最佳实践。 ### 24. 学习并理解C++的内存管理机制 C++允许程序员直接操作内存,这...

    C++LogFactory( Logfile)

    接下来,我们讨论日志记录的基本概念。日志通常包含时间戳、日志级别(如DEBUG、INFO、WARNING、ERROR)、发生事件的模块或函数名,以及实际的日志消息。日志级别用于区分重要性,方便在排查问题时快速定位关键信息...

    学习C++的四个层次(美化版)

    - **《C++沉思录》**:作者通过一系列的思考题引导读者思考C++编程的各种细节,有助于提高解决问题的能力。 - **《STL源码剖析》**:深入研究STL的实现原理和源代码,非常适合想要深入了解标准库内部机制的人。 - **...

    数据库c++ 医院门诊管理系统

    首先,我们来讨论C++在数据库管理系统中的应用。C++是一种强大的、面向对象的编程语言,具有高效性、灵活性和丰富的库支持。在构建医院门诊管理系统时,C++可以用于实现数据结构、用户界面和系统逻辑。通过C++的类和...

    Thriving in a Crowded and Changing World - C++ 2006–2020.pdf

    在技术细节上,C++标准库构成了C++20标准的约四分之三,但论文的重点是语言特性及其支持的编程技术。标准的演变旨在通过逐步的改变保留C++的本质,同时简化其使用,改进泛型编程,更好地支持编译时编程,扩展对并发...

    学习c++的50个忠告

    相比之下,《C++变成死相》可能更多地关注于语言的细节和技巧,但缺乏对于编程思想的指导。 #### 3. 看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者...

    C++实现的PC 游戏编程之中国象棋

    总的来说,"C++实现的PC 游戏编程之中国象棋"项目涵盖了C++编程基础、面向对象设计、游戏规则逻辑、决策算法、图形用户界面和机器学习等多个方面的知识。通过这个项目,开发者不仅可以提升编程技能,还能深入理解...

    Working Draft Standard for Programming Language C++

    5.7 **注释**:定义了C++中可用的注释风格,帮助开发者记录代码。 5.8 **头文件名**:规定了头文件命名的规则和约定。 5.9 **预处理数字**:描述了预处理器如何处理数字常量。 5.10 **标识符**:定义了标识符...

    C++ Builder5开发人员指南.zip(.pdf)

    VCL组件库使得开发者能够通过拖放方式快速构建用户界面,而无需关心底层的Windows API细节。此外,还会有涉及事件驱动编程模型的讨论,帮助读者理解如何响应用户操作。 C++ Builder 5支持面向对象编程,书中的章节...

    基于c++简单聊天室

    7. **总结与反思**:总结实验过程中的收获,分析项目中的不足之处,以及可能的改进方向,如增加加密以保护通信安全,支持更多用户同时在线,或者添加图形用户界面(GUI)以提供更好的用户体验。 通过这个项目,...

    meter改进 c++

    在IT行业中,C++是一种强大的、面向对象的...不过,由于该文件未提供具体内容,这里只能基于“Meter改进 C++”这个主题进行一般性的讨论。对于实际的代码实现和改进细节,需要查看文件内容才能给出更具体的分析和建议。

    LZSS压缩算法C++源代码

    接下来,我们讨论C++类的封装。封装是面向对象编程的核心概念,它将数据和操作数据的方法绑定在一起,形成一个独立的实体——类。在这个LZSS压缩算法的实现中,类可能包含以下组成部分: 1. **成员变量**:可能包括...

    C++实现的网上拍卖系统

    当然,实际的项目可能还需要考虑更多细节,如安全性、性能优化等,但以上的讨论已为我们提供了一个基本的架构和思路。在实践中,不断迭代和完善,才能真正打造出一个高效、稳定的网上拍卖系统。

    简单的C++员工工资管理系统

    下面将详细讨论这个系统可能涉及的C++知识点、数据库操作和员工工资管理的基本概念。 1. C++基础知识: - 类与对象:C++是一种面向对象的编程语言,员工工资管理系统会涉及到类的设计,如`Employee`类用于封装员工...

    c++获取某一软件安装路径

    在本篇文章中,我们将深入探讨如何使用C++获取特定软件如360的安装路径,并且讨论如何通过调整代码来适应其他软件。 首先,我们要明白操作系统对软件安装路径的管理和访问方式。在Windows系统中,通常每个软件都有...

Global site tag (gtag.js) - Google Analytics