1.函数参数进栈顺序:从右到左2.字符串化预处理特征:在表达式前加上‘#’表示将仍和一个表达式转化成一个字符串。3.解析一个变量的类型:从中间向外扩展,先右再左,大多数的声明以左"/>

Somethings About 《c++编程思想》

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Somethings About 《c++编程思想》相关的知识,希望对你有一定的参考价值。

以下为博主呕心沥血的总结,看的时候要珍惜一点,答应我!技术分享


1.函数参数进栈顺序:从右到左

2.字符串化预处理特征:在表达式前加上‘#’表示将仍和一个表达式转化成一个字符串。

3.解析一个变量的类型:从中间向外扩展,先右再左,大多数的声明以左-右左完成(具体结合运算符的优先级来判断)

     eg: 

     1. void*( * ( *pfun )( int ) )[ 10 ]    

     解析:pfun是一个函数指针,指向一个参数是int返回值是一个只想有10个void*元素的数组的指针

     2.float(* ( *fp2 ) ( int ,int,float ) )( int )

      解析:fp2是一个函数指针,指向参数列表是int,int,int返回值是一个函数指针的函数。

     (返回值里的函数指针指向一个返回值是float 参数列表是int)

4.创建函数指针数组,支持“表格驱动码”概念:可以根据状态变量选择函数而不用条件判断。

    eg:

    #define     DF (N ) void N (){         cout << "函数"#N"被调用..." << endl ; }
    DF(a); DF( b); DF(c); DF (d ); DF( e); DF(f); DF (g );
    void(*func_table [])() = { a, b , c, d , e, f, g };
    int main ()
    {
         while (1)
         {
                cout << "press a key from ‘a‘ to ‘g‘,or ‘q‘" << endl;
                char c;
                cin. get( c);
                if (c == ‘q‘ )
                     break;
                if (c >= ‘a‘ && c <= ‘g‘)
                     (*func_table [c - ‘a‘ ])();
                else
                     continue;
         }
         return 0;
    }

5.makefile行为(p101)

6.任何情况下都不允许同时使用两个具有同名函数的C库

7.C++:对象必须要有唯一的标识,对象即变量

8.将函数捆绑在数据结构内部的语言是基于对象而不是面向对象

9.全局作用域解析直接使用::前面不加任何限定

10.嵌套结构的友元:先声明这个结构->再声明它是一个友元结构->最后定义

11.句柄类:头文件放置公共的接口和一个单指针。

                  所有成员函数的定义一同出现在实现文件中,只要接口部分不变头文件就不要改动                    

                  具体实现的结构被隐藏在实现的文件中。

12.联合不能作为基类使用

13.C++的const默认为是内部连接属性,所以在定义时必须给他一个值,除非使用extern来说明

14.关键字static :不管类被实例化多少次,所有对象都只拥有同一份static实例

15.enum hack:将匿名枚举嵌套在类中,我们就可以将枚举里的数据当成static const

16.const对象:保证该对象的数据成员在其生命期内不被改变

17.const函数:必须保证将const置于参数列表的后面,不修改数据成员的函数都应该把它们声明为const

     构造和析构都不是const函数,因为他们总数对数据成员做了一定的修改

18.关键字mutable :指定一个特定的数据成员可以再const对象里面被改变! 

19.关键字volatile:告诉编译器:“请不要随便假设,并且消除冗余代码。”

                              在编辑器认识的范围外该数据可以被改变!

20.C++的弱类型(模板):一个类型想要调用的成员函数对于一个特定的对象可用

21.return 一个匿名对象和一个非匿名对象是不同的(返回值优化)

     eg: 

         return 类名(数据);

         // 这里编译器直接把这个对象创建在外部返回值的内存单元


          类名 对象名;

          return 对象名(数据);

          //编译器首先创建对象,然后将对象拷贝构造给外部返回值的内存单元里,最后再将tmp析构 

22.嵌套的友元类:先声明类名,再声明友元,最后定义

23.operator->*:可以直接调用成员函数(p515)

     流程:operator->*(函数指针)->返回一个匿名对象

               调用operator()

               获得间接引用(真实的)指向成员的指针

     *仅用于参数和返回值是int的指针

24.不能重载的运算符:.    .*(成员指针的间接引用)   **   ::    ?:  

25.输入输出流最好作为友元原因:运算符>>和<<的左侧操作数是ostream的对象和istream的对象,

                                                    如果按照正常的思维将其定义出来调用时只能这样:对象名<<cout;

技术分享

26.自动类型转换:当编译器发现一个表达式或者函数使用了一个不合适的类型,他进行类型转换

   A.构造函数转换:当编译器看到类A的方法调用了类B的对象。

      而A的构造函数传参是B类型的,它就会先调用这个构造函数啦

      如果你不想这样的方式发生的话就在构造函数前加上explicit关键字

   B.运算符转换:没有指定返回类型的operator 可以将当前类型转换成为希望的类型

     eg:

            A::operator B() const {return B(_data);}//_data是A类的数据成员

   *可以做到从用户定义类型向内置类型的转化

27.全局重载运算符可体现反身性,成员版本必须保证左侧操作说处于正确的形式!

28.自动类型转换的缺陷

    a.复杂的类型转换

技术分享

    *编译器此时认为这是一个不明指示

    b.扇出:在一个类中提供了多种类型的自动转换函数的重载

    c.隐藏的行为。

29.栈分配运算内置于处理器的指令集里

30.如果delete一个void 指针则不会调用析构函数(这将是一个程序的错误)

    *如果程序出现内存丢失的现象记住检查每一个被delete的指针的类型!

31.容器中含有void*类型的指针,所以他们不能自己管理指针必须由我们负责清除这些对象

    *不要讲指向栈上内存的指针和指向堆上内存的指针存放在同一个容器里!

32.尽量将指向数组的指针用const修饰

33.new-handler函数

34.组合:在新类中创建已存在的类的对象

35.构造函数的初始化表达式表:D::D(int data):Bar(data), m(data+1){}

36.组合和继承的选择

     组合:希望新类具有已存在的类的方法

     考虑:你是否需要向上类型转换

38.渐增式开发:允许在已存在的代码中引入新代码,并且新代码不会导致已存在的代码发生错误

39.向上类型转换:使用基类指针类型调用子类方法

40.可扩展性:只和基类通信接口

41.派生类如果继承的是一个抽象类那么它必须实现基类所有的纯虚函数(抽象方法)

42.RTTI:运行时确认

43.对象切片:虚函数使用了传值调用

44.不把析构函数设置为虚函数是一个隐匿的错误,可能会引入存储器泄漏    


本文出自 “Zimomo” 博客,请务必保留此出处http://zimomo.blog.51cto.com/10799874/1759571

以上是关于Somethings About 《c++编程思想》的主要内容,如果未能解决你的问题,请参考以下文章

用C++编程思想解决一道题

JAVA编程思想中总结的与C++的区别

Kotlin 或将取代 Java —— 《Java 编程思想》作者 Bruce Eckel

Java编程思想学习 一切都是对象

使用 lambda 作为 C++ 函数的参数

Java编程思想 4th 第2章 一切都是对象