《Essential C++》读书笔记

本文深入探讨了C++编程的多种风格,包括面向过程、泛型、基于对象及面向对象编程,详细讲解了迭代器和函数对象的实现,以及模板编程和异常处理的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2 面向过程的编程风格

  1. 建议在传递内置类型时,不要使用传址方式;传址机制主要用于传递class object

  2. 函数默认参数值只能够指定一次,可以在函数声明处,亦或在函数定义处,但不能够在两个地方点后指定;一般在头文件指定

  3. 函数重载:参数列表(参数类型、参数个数)不相同的两个或多个函数,类成员函数是否有const

  4. 头文件使用 " " 而非< >
    < > 认定为标准的或项目专属的头文件,编译器搜索此文件时,会先在某些默认的磁盘目录中搜寻

    " " 认定是一个用户提供的头文件,搜索此文件时,会由要包含此文件的文件所在的磁盘目录开始找起

3 泛型编程风格

iterator(泛型指针)引入

实现一个find函数,同时支持vector和array
template<typename elemType>
elemType* find(const elemType *first, const elemType *last, const elemType &value)  //last  标兵
{
      if(!first || !last)
      {
             return 0;
      }
      for (; first!=end; first++)
      {
             if (*first == value)
                    return first;
      }
      return 0;
}
缺陷:
vector<string> svec;    //为空
find(&svec[0], &svec[svec.size()], search_value);    //出错
改进版:
//重写取第一个元素、最后一个元素
template<typename elemType>
inline elemType* begin(const vector<elemType> &vec)
{
       return vec.empty() ? 0 : &vec[0];
}

template<typename elemType>
inline elemType* end(const vector<elemType> &vec)
{
       return vec.empty() ? 0 : &vec[vec.size()];
}

find(begin(svec), end(svec), search_value);
支持list?    
NO。vector、array所有元素存储在连续的空间里,才可以指针++指向下一个元素。

解决方法:
在底层指针的行为之上提供一层抽象。
template<typename IteratorType, typename elemType>
IteratorType find(IteratorType first, IteratorType last, const elemType &value)
{
       for (; first != end; first++)
       {
              if (*first == value)
                     return first;
       }
       return last;
}
如果并未提供==运算符,或用户希望赋予==运算符不同的意义?

解决方法:
函数指针、function object   ====》将某行为传给函数
  1. 函数指针
vector<int> filter(const vector<int> &vec, int filter_value, bool (*pred)(int,  int))
{
     vector<int> nvec;
     for (int ix = 0; ix < vec.size(); ix++)
            if (pred(vec[ix], filter_value))
                   nvec.push_back(vec[ix]);
     return nvec;
}

//pred的一种比较方式
bool less_than(int v1, int v2)
{
     return v1 < v2 ? true : false;
}
  1. function object见第4章

4 基于对象的编程风格

4.1 实现Iterator class

class Triangular_iterator
{
public:
     Triangular_iterator(int index) : _index(index-1){ }

     bool operator==(const Triangular_iterator& rhs) const
     {
           return _index == rhs._index;
     }

     bool operator!=(const Triangular_iterator& rhs) const
     {
           return !(*this == rhs);
     }

     int operator*() const
     {
           check_integrity();
           return Triangle::_elems[_index];
     }

     Triangular_iterator& operator++()          //前置
     {
           ++_index;
           check_integrity();
           return *this;
     }

     Triangular_iterator operator++(int ) //后置
     {
           Triangular_iterator tmp = *this;
           ++_index;
           check_integrity();
           return tmp;
     }

private:
     void check_integrity() const
     {
           if(_index >= Triangle::_max_elems)
                throw iterator_overflow();
           if(_index >= Triangle::_elems.size())
                Triangular::gen_elements(_index+1);
     }

     int _index;
};

class Triangle
{
public:
     typename Triangular_iterator iterator;        //让用户不必知道iterator class的实际名称

     Triangular_iterator begin() const
     {
           return Triangular_iterator(_beg_pos);
     }

     Triangular_iterator end() const
     {
           return Triangular_iterator(_beg_pos+_length);
     }

     friend int Triangular_iterator::operator*();
     friend void Triangular_iterator::check_integrity();

private:
     int _beg_pos;
     int _length;
     int _max_elems;
     static vector<int> _elems;
};

int main()
{
     Triangle tri(20);
     Triangle::iterator it = tri.begin();
     Triangle::iterator end_it = tri.end();
     while (it != end_it)
     {
           cout<<*it<<' ';
           ++it;
     }
     cout<<endl;
}

4.2 实现function object

lt(ival); //lt可能是函数名称、可能是函数指针、可能是一个提供了function call运算符的function object
class LessThan
{
public:
     LessThan(int val):_val(val){ }
     bool operator( )(int value) const            //可以接受任意个数的参数
     {
           return value < _val;
     }
private:
     int _val;
};

int count_than(const vector<int> &vec, int comp)
{
     LessThan lt(comp);
     int count = 0;
     for(int ix=0; ix<vec.size(); ++ix)
     {
           if(lt(vec[ix]))
                ++count;
     }
}

//把function object 当做参数传递给泛型算法
void print_less_than(const vector<int> &vec, int comp, ostream  &os=cout)
{
     LessThan lt(comp);
     vector<int>::const_iterator iter = vec.begin();
     vector<int>::const_iterator it_end = vec.end();
     while ((iter=find_if(iter, it_end, lt)) != it_end)
     {
           os<<*iter<<" ";
           ++iter;
     }
}

5 面向对象编程风格

  1. 动态绑定:
    找出实际被调用的究竟是哪一个派生类的函数这一解析操作会延迟至运行时(run-time)才进行。

  2. 凡基类定义一个(或多个)虚函数,应该将其destructor声明为virtual

  3. 类中的Data member如果是个reference,必须在constructor的member initialization list中加以初始化

  4. 在基类的constructor(destructor)中调用虚函数,一定会解析为基类自身的那一份虚函数

6 以template进行编程

以初始化列表对类型参数进行初始化,而不选择在函数体内进行
//方式1
template<typename valType>
inline BTnode<valType>::BTnode(const valType &val):_val(val)
{
    _cnt = 1;
    _lchild = _rchild = 0;
}

//方式2
template<typename valType>
inline BTnode<valType>::BTnode(const valType &val)
{
    _val = val;

    _cnt = 1;
    _lchild = _rchild = 0;
}
将valType指定为内置类型int,
BTnode<int> btni(42);
两种形式效率上没有差异。

BTnode<Matrix> btnm(transform_matrix);

第一种方式只需以copy constructor 将val复制给_val

第二种方式_val赋值操作分为两个步骤;
(1)Matrix的default constructor会先作用于_val
(2)函数体内会以copy assignment operator将val复制给_val

7 异常处理

  1. 异常处理机制:
    1)异常的鉴定与发出
    2)异常的处理方式

  2. 抛出一个异常 (异常是某种对象)
    throw 42;
    throw “panic :no buffer”;

  3. 重新抛出异常

try
{

}
catch( ... )        //捕获任何异常
{
    。。。
    throw}
  1. C++规定,每个异常都应该被处理,如果在main()内还找不到合适的处理程序,便调用标准库提供的terminate(),默认行为是中断整个程序的执行。
### 回答1: 《Essential C》是一本C语言入门教材,它每一章节都设计了实例来帮助读者理解概念和语言基础。电子版则更方便了读者的阅读和学习。 电子版提供了搜索和书签功能,读者可以根据自己的需求快速找到需要的内容并添加书签方便以后查阅。此外,电子版还可以进行自定义设置,例如字体大小、背景颜色等,可以适应个人的视力和阅读习惯。 另外,与统纸质书不同,电子版可以在不同设备上进行阅读,无论是手机、平板还是电脑等,都可以随随地进行学习。在线阅读还能通过云端同步功能实现多设备共享,无需反复购买纸质版或电子版。 总之,《Essential C》电子版具有方便、灵活、多样化的优点,可以提高学习效率和便利性,是入门C语言学习者的好帮手。 ### 回答2: Essential C是一本C语言的经典教材,在C语言学习领域有着重要的地位。它浅显易懂,通俗易懂的文字风格以及丰富的示例代码,为初学者提供了优秀的学习资源。 Essential C电子版的出现,更加方便了广大编程爱好者的学习。电子版易于获取、拷贝和搜索,而且免费提供下载,无需支付任何费用。同,它还能在不同的设备上进行阅读,让学习变得更加灵活。 电子版还具有与纸质版不同的特点。它可以轻松地添加笔记、书签等功能,方便读者随回忆所学习的知识点。此外,电子版还提供了灵活的屏幕阅读方式,通过缩放和改变字体大小、背景色等方式来使读者更加舒适的阅读。 不过,电子版也存在一些缺点。因为它需要电子设备才能进行阅读,所以它的可移动性和泛用性相较于实体书籍较低。此外,对于想要离线阅读的读者,电子版便不具有实体书籍的优势。 综上所述,Essential C电子版为学习C语言的初学者提供了更加方便、灵活的学习方式,但它并不能完全替代实体书籍,两者都有自己的优缺点,而最终选择哪一种方式取决于读者自身的需求和使用习惯。 ### 回答3: Essential C是一本C语言程序设计的入门级教材,在学习C语言的过程中,是十分实用的一本教材。其电子版更是让读者们便于随随地进行阅读学习,更加方便。 Essential C的电子版为读者带来了许多便利,首先在阅读上,不受到纸质版阅读的间和地点的限制,可以通过任何一台电子设备,如电脑,手机,平板等就能轻松阅读。其次,在使用上,电子版更加方便了读者的查找和学习体验,例如增加了搜索功能,让读者更加便捷地找到所需要的内容,并且还能够进行注释和标记,极大提高了学习效率。 同Essential C的电子版还可以对其内容进行快速更新升级,保证其内容始终和代同步,并且在学习之外,电子版还可进行交互式教学。比如说,在阅读的同可以进行代码编辑等操作,相比于统的纸质版,更具有互动性和趣味性。 总之,Essential C的电子版在方便性、使用性、更新性、互动性方面都具有很大优势,更加适合现代读者的学习习惯,极大地促进了C语言的教学工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值