读《高质量C++编程》总结

今天翻了一遍《高质量C++编程》,为了以后再次回顾,做了如下记录与一些自己的总结。

1.头文件包含问题

为了防止头文件被重复引用,应当用 ifndef/define/endif 结构产生预处理块。

   也可以使用另一种方式:#pragma once  相信很多人知道,作用和上面是一样的。


2.循环语句效率

在多重循环中,如果可以,应当将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数

如:

for(i = 0; i<500; i++)

{

    for(j=0; j<10; j++)

    {

          //xxx

    }
}//不良写法


应改为:

for(i = 0; i<10; i++)

{

    for(j=0; j<500; j++)

    {

          //xxx

    }
}

另外,如果循环体内存在逻辑判断,并且循环次数很大,可以将逻辑判断移到循环体的外面


3.switch语句

Java中

1. byte、char、short、int四种基本类型以及它们的包装类(需要Java5.0/1.5以上版本支持)都可以用于switch语句。

2. long、float、double、boolean四种基本类型以及它们的包装类(在Java所有版本中)都不能用于switch语句。

3. enum类型,即枚举类型可以用于switch语句,但是要在Java5.0(1.5)版本以上才支持。

4. 所有类型的对象(包括String类,但在Java5.0/1.5以上版本中,该项要排除byte、char、short、int四种基本类型对应的包装类)都不能用于switch语句。

 

C++中

1. char、short、int、long、bool四种基本类型都可以用于switch语句。

2. float、double都不能用于switch语句。

3. enum类型,即枚举类型可以用于switch语句。

4. 所有类型的对象都不能用于switch语句。(比如string,可以自己试试)


4.常量

1.不能在类声明中初始化 const 数据成员

class A
{…
    const int SIZE = 100;    //  错误,企图在类声明中初始化 const 数据成员
    int array[SIZE];     //  错误,未知的 SIZE
};

2.const 数据成员的初始化只能在类构造函数的初始化表中进行

class A
{…
    A(int size);    //  构造函数
    const int SIZE ; 
};
A::A(int size) : SIZE(size)  //  构造函数的初始化表
{
    …
}

3.C++中的常量用const声明,C语言中用的是#define。

   const最大的用处是用在函数的参数修饰,比如函数的一个参数是指针,如果这个函数在以后的工作中不会改变指针指向的变量的话,要在指针前加const,避免以后意外的改变。


5.static成员变量与函数

   static类型的类成员变量必须在类外初始化;

   static成员函数不依赖于类,相当于类里的全局函数(可以由该类对象调用,也可以 类名::函数名()的形式调用)

   static成员函数相当于把访问范围限制在所在的类中!  注意:不能访问类中非static成员变量以及成员函数。

   static成员函数在实际中可以用作线程函数


6.指针与引用

    如果函数的返回值是一个对象,有些场合用“引用传递”替换“值传递”可以提高效率。而有些场合只能用“值传递”而不能用“引用传递” ,否则会出错。

例如:

class String
{…
    //  赋值函数
    String & operate=(const String &other);  
    //  相加函数,如果没有 friend 修饰则只许有一个右侧参数
    friend  String operate+( const String &s1, const String &s2); 
private:
    char *m_data; 
}:


String 的赋值函数 operate =  的实现如下:
String& String::operate=(const String &other)
{
    if (this == &other)
           return *this;
    delete m_data; 
    m_data = new char[strlen(other.data)+1];
    strcpy(m_data, other.data);
    return *this;   //  返回的是 *this 的引用,无需拷贝过程
}

对于赋值函数,应当用“引用传递”的方式返回 String 对象。如果用“值传递”的
方式,虽然功能仍然正确,但由于 return 语句要把*this 拷贝到保存返回值的外部存
储单元之中,增加了不必要的开销,降低了赋值函数的效率。


String 的相加函数 operate +  的实现如下:

String operate+(const String &s1, const String &s2)  
{
    String  temp;
    delete temp.data;  // temp.data 是仅含‘\ 0’ 的字符串
    temp.data = new char[strlen(s1.data) + strlen(s2.data) +1];
    strcpy(temp.data, s1.data);
    strcat(temp.data, s2.data);
    return temp;
}

对于相加函数,应当用“值传递”的方式返回 String 对象。如果改用“引用传递”,
那么函数返回值是一个指向局部对象 temp 的“引用”。 由于 temp 在函数结束时被自动销毁,将导致返回的“引用”无效


7.extern c的问题

如果 C++ 程序要调用已经被编译后的 C 函数,该怎么办?
假设某个 C 函数的声明如下:
void foo(int x, int y);
该函数被 C 编译器编译后在库中的名字为_foo,而 C++编译器则会产生像_foo_ int_ int之类的名字用来支持函数重载和类型安全连接由于编译后的名字不同,C++ 程序不能直接调用 C 函数。C++ 提供了一个 C 连接交换指定符号 extern “C”来解决这个问题。
例如:
extern “C”
{
    void foo(int x, int y);
    … // 其它函数
}
或者写成
extern “C”
{
     #include “myheader.h”
     … // 其它 C 头文件
}
这就告诉 C++ 编译译器,函数 foo 是个 C 连接,应该到库中找名字_foo 而不是找
_foo_int _ int 。C++ 编译器开发商已经对 C 标准库的头文件作了 extern “C”处理,所以我们可以用#include  直接引用这些头文件。


8.参数缺省值

参数缺省值只能出现在函数的声明中,而不能出现在定义体中。
例如:
void Foo(int x=0, int y=0);  //  正确,缺省值出现在函数的声明中
void Foo(int x=0, int y=0)     //  错误,缺省值出现在函数的定义体中
{

}


9.运算符重载

如果运算符被重载为全局函数,那么只有一个参数的运算符叫做一元运算符,有两个参数的运算符叫做二元运算符。
如果运算符被重载为类的成员函数,那么一元运算符没有参数,二元运算符只有一个右侧参数,因为对象自己成了左侧参数



10.重载、覆盖与隐藏

成员函数被重载的特征:
(1 )相同的范围(在同一个类中);
(2 )函数名字相同;
(3 )参数不同;
(4 )virtual 关键字可有可无。


覆盖是指派生类函数覆盖基类函数,特征是:
(1 )不同的范围(分别位于派生类与基类);
(2 )函数名字相同;
(3 )参数相同;
(4 )基类函数必须有 virtual 关键字。

隐藏:

(1 )如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无 virtual
关键字,基类的函数将被隐藏
(注意别与重载混淆)。
(2 ) 如果派生类的函数与基类的函数同名, 并且参数也相同, 但是基类函数没有 virtual
关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。


(未完待续...)

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值