• 读《effective C++》1


    条款一:视C++为一个语言联邦


    学习C++半个月了,学了他的面向过程编程,面向对象编程(封装性,继承性,多态性),template泛型编程,开始只是觉得C++基础是面向对象,但是学了这么多块开始有点迷糊,而条款一很好的解释了我的迷惑。

    “C++已经是个多重范型编程语言(multiparadigm programming language),一个同时支持过程形式,面向对象形式,泛型形式,元编程形式的语言。”

    而在这么多无敌的工具下,我们如何去理解这么一个语言呢?

    将C++视为有相关语言组成的联邦而非单一的语言(相关语言称之为“次语言”)” 面对每个次语言都有自己的守则(对一些工具的选择)或者通类。

    而幸运的是C++中次语言只有四个:

    1.C。 说到底C++就是以C为基础的。基础语法(内置数据类型,预处理器,数组,指针)都来自C语言,只不过C++的解法较之C更高级一点。

    2.Object-Oriented C++。 :这部分包含类,封装性,继承性,多态性,虚函数,这部分是面向对象设计在C++的直接实施。

    3.Template C++。 泛型C++设计,现在的主流设计思想

    4.STL。完美的把容器,迭代器,算法,函数对象紧密配合和协调。

    当你从某个次语言切换到另外一个次语言时,会导致你的编程守则策略的改变。

    比如对参数传递策略的选择上,在内置类型(C-Like)类型而言,pass-by-value(值传递)通常比pass-by-reference更高效(所以不能认为引用传递是最好的),而当你面对是自定义对象或者是Template C++中,pass-by-reference-const会是更好的选择。

    所以,总之,对C++的理解分为四个次语言来理解,并且对策略的选择因为次语言的不同去选择。

    条款二:尽量以const,enum,inline代替 #define


    1.const常量

    自从const在C++出现以后,#define 就一直受在排挤,因为他在很多时候存在很多的隐患。因为他不能被分配内存空间,出错的时候很难追踪到错误信息。

    (1)常量指针(const pointer)

    这是一个比较常见的const话题,比如:

    1 const int *p;       //
    2 int const *p;      //前面两种形式不一样,但是是同一种。都是指针所指向的变量是修饰为常量
    3 int *const p;          //const修饰的是指针变量本身,指针变量本身是常量
    4 const int *const p;    //合以上两者

    C++在C的进阶:

    const char *const authorName = "Scott Meyers";
    //string对象通常比他的前辈char*更合适一点。
    const std::string authorName("Scott Meyers");

    (2)class专属常量

    两个条件:该变量是常量,且必须是在类的作用域范围

    class GamePlyer
    {
    private:
          static const int NumTurns = 5;//这是初始化方式中唯一能在类声明时初始化的方式
          int scores[NumTurns];   //使用该变量       
    };

    作者很遗憾的告诉你“然而,你看到的只是声明式而非定义式”

    只要你不取地址,你可以声明并且使用它们而无须提供定义式

    //定义式
    const int GamePlayer::NumTurns; //这里不用给予数值是因为声明时已经获得初值了,所以这里不需要再给予。

    #define  是无法创建这样的专属常量的,因为它并不重视作用域,所以导致其不能提供封装性的要求。

    2.the enum hack

    【1】enum(枚举类型):学习C语言的时候就没有重视这个知识点,好几次,连基本概念都没有搞清楚,现在看到都不知道什么意思,这是个不好的习惯。

     枚举类型:如果一个变量只有几种可能的值,则可以用枚举来解决,这在实际生活中很实用。(这也是为什么枚举不倒的原因吧)

    enum Weekday{sun,mon,tue,wed,thu,fri,sat};    //声明
    enum Weekday workday,weekend;   //定义枚举变量
    /*
    1.在C语言中,enum Weekday是该变量类型,但是在C++中解除了这种麻烦的声明变量名,可以直接使用类型名,不必带上enum
    2.{}中的sun,mon,...,sat是枚举元素或者枚举常量。是用户自定义的,也是设计者根据需要命名的,注意这里它虽然是标示符,但是不能当做变量,这里编译器是把它当做常量处理,默认第一个是0,然后顺序下去,mon的值为1...也可以自己认为指定值。后面的顺序加1.
    3.枚举也可以做判断比较
    if(workday == mon)...
    if(workday > sun)...
    */

    【2】SM(作者Scott Meyers)enum类型变量有const没有的,

    用他的话来说就是:“基于数个理由enum hack值得我们认识”

    (1)enum hack的行为某方面比较像#define而不像const,有时候这是我们想要的。

    获取一个const的地址是合法的,而获取一个enum的地址是不合法的,通常取一个#define 的地址也是不合法的。当你不像别人通过pointer或者reference指向你的 某个整数常量,enum可以帮助你实现这个约束。并且enum不会浪费不必要的内存分配。

    (2)纯粹的为了实用主义

    这句话足以让你想去了解enum hack   “事实上,enum hack是template 模板元编程的基础”

    并且我最近学习Qt编程,阅读帮助文档几乎随处可以见到枚举类型的编程。

    3.inline替换#define函数行为

    #define 定义函数行为我用的不多,但是看一些比较牛的大赛里面,C语言的宏定义函数很是厉害,但是这是对于那些大牛而言,因为#define 函数行为实在是存在太多的隐患,因为他是纯粹的替代,并不会处理,而这会导致很多形式上的错误,无法想象,所以,我这里按照SM(作者Scott Meyers)的说法,用inline函数替代这个麻烦的东西。

    //一般使用template inline
    template<typename T>
    inline void callWithMax(const T& a, const T& b)
    {
          return  a>b?a:b;      
    }
  • 相关阅读:
    JavaScript的兼容小坑和调试小技巧
    前端jQuery实现瀑布流
    angular常用属性大全
    Eclipse易卡死
    工作反思
    半年回忆
    努力做到
    产品经理如何应对技术的「做不了」这样的问题(转)
    优秀的产品经理我还有多远
    简历技巧
  • 原文地址:https://www.cnblogs.com/panhao/p/4514353.html
Copyright © 2020-2023  润新知