`
bollaxu
  • 浏览: 217109 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

C++ Standard Library--Chapter 2 & Chapter 3

阅读更多

Chapter 2 Introduction to C++ and the standardy library

 

这章主要是概括地讲一些关于C++的历史和特性。

C++的标准化过程从1989年就开始了,直到1997年才结束(制定标准的过程很漫长,伴随着多方的努力和协商)。不过按照作者的意思,标准化还是没有达到完美的程度,但是产生了一些基本的库和组件(如string,IO,数据结构和算法等)。其实标准化的目标根本就不是为了开发一套全新的库,而是为了整合一些已经存在的库和设计理念(IOStream类就是很好的一个例子,它在1984年已经有了,为了追求兼容性,C++保留了它原来的实现)

 

STL(standardy template library)里面有很多数据结构和算法,在实现过程中也是为了追求语言最好的效率,所以使用者必须对STL有着很好的了解。

 

作者也提到了,标准化的过程是由全世界的数以百计的人共同参与的,中间经历了无数的讨论。在1994年的时候,为了让标准化过程尽快结束,制定者决定不再考虑更多的扩展性,所以一些目前很常用年的数据结构像hash表等,就没有在标准里面。

 

新特性:

1. 模板。几乎所有的STL都是以模板的概念来实现的。所谓模板,就是在一些没有特别标明数据类型的类和函数。书中就有一个例子:

 

template <class T>
inline const T& max (const T& a, const T& b)
{
   //if a < b then use b else use a
   return a < b ? b : a;
}

 在上面的例子里面,T 就是一个任意的数据结构,在调用这个函数的时候再进行指定的。很多类也是用这种方法来实现的。值得注意的是,template模板不是只被编译一次就可以用了,而是在编译器找到使用模板的地方,再根据具体的数据结构进行编译的。所以,在编译的时候模板必须已经在之前定义好了。通常,模板会定义在头文件里面,病使用inline做限制(*inline跟宏类似,但是更加灵活,主要原理就是在使用inline定义的函数/变量的时候,编译器自动把定义的代码复制一份,以提高性能。注:对于代码量大而频繁使用的函数反而会因为代码膨胀过大而伤害到性能)。

 

2. typename。用来表示后面跟的是一个类型。例如:

 

template <class T>
Class MyClass {
   typename T::SubType * ptr;
   ...
};

 这儿typename就声明了SubType是T里面的一个类型,ptr是指向T::SubType的一个指针。如果没有typename,那么SubType会被认为是T的一个静态成员,T::SubType * ptr的意思就是两个变量的乘积。另外typename也可以替换class来用,比如 template <typename T> class MyClass;

 

3. 类里面的成员函数也有可能是模板。这个特性可以支持类型的转换。例如函数不定义为模板:

 

template <class T>
class MyClass {
   private:
      T value;
   public:
      void assign (const MyClass<T>& x) {
      // x must have same type as *this
         value = x.value;
      }
       ...
};

 在这儿,一旦使用assign()函数并传入一个类型的参数,那么value就会自动的转成同一类型。错误调用就会造成编译出错。

 

void f()
{
   MyClass<double> d;
   MyClass<int> i;

   d.assign(d); //OK
   d.assign(i); //ERROR: i is MyClass<int>, 
                      //but MyClass<double> is required
}

如果使用模板来定义的话,上面的语句就不会出错:

template <class T>
class MyClass<T> {
   private:
      T value;
   public:
      template <class X>                           //member templates
      void assign (const MyClass<X>& x) {//允许不同的类型
         value = x.getValue();
      }
      T getValue() const {
         return value;
      }
      ...
};

 

4. 异常处理。try {} catch {}语句

5. 名字空间。为了防止类/函数等名字冲突。

6. bool。boolean类型

7. explicit关键字。检查传入类型是否匹配,不会像c那样把不匹配的类型转换。

8. 类型转换操作符

    a. static_cast。例:float x; cout << static_cast<int>(x); 

    b. dynamic_cast。把基类转化成子类(多态性),例:

 

class Car; //abstract base class; has at least one virtual function

class Cabriolet : public Car {
   ...
};

class Limousine : public Car {
   ...
};

void f (Car* cp)
{
   Cabriolet* p = dynamic_cast<Cabriolet*>(cp);
   if (p == NULL) {
        //p did not comfort to Cabriolet
        ...
   }
}

   c. const_cast。转化成const或者取消const限制;取消volatile限制

   d. reinterpret_cast。根据具体的实现而定。

 

9. main函数只能定义为int main(){...}或者int main(int argc, char *argv[]){...}或者int main(int argc, char **argv){...}。如果最后没有return语句,c++会自动给main函数加return 0。但是部分编译器仍然不允许不加return语句。

 

 

 

Chapter 3 Generic Concepts

 

本章主要讲了C++几个基本的概念。

 

1. 名字空间。主要用来防止函数/类名字冲突。

2. 头文件。C++的标准库的头文件在include的时候不用加.h,.hpp,hxx的后缀。

3. error和exception的处理。把exception分成了几个类别:支持语言特性的exception(如bad_alloc, bad_cast等);标准库的exception(主要都是logic error,如invalid_argument,out_of_range等);运行时的exception(如overflow, underflow等)。

4. allocator分配器。主要用于对对象的内存分配和释放,在原始的内存分配和释放上封装一层,使用者无需知道内存是如何被分配,分配了多少等。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics