【摘要】 C++次语言 C(区块,语句,预处理器,内置数据类型,数组,指针)、面向对象C++(类,封装,继承,多态virtual)、模板C++(泛型编程)、STL库。
以编译器替换预处理器 预处理器(.cpp):C++采用的是词法预处理器,主要进行文本替换,宏展开,删除注释这一类的简单工作。预处理器不进行语法检查,因为它不具备语法检查功能,并且预处理命令不属于C++语句。所…
- C++次语言
C(区块,语句,预处理器,内置数据类型,数组,指针)、面向对象C++(类,封装,继承,多态virtual)、模板C++(泛型编程)、STL库。
- 以编译器替换预处理器
- 预处理器(.cpp):C++采用的是词法预处理器,主要进行文本替换,宏展开,删除注释这一类的简单工作。预处理器不进行语法检查,因为它不具备语法检查功能,并且预处理命令不属于C++语句。所谓预处理,是将程序中的宏展开,以及将头文件的内容包含进来,预处理不会生成文件,因此需要重新定向。经过预处理之后,才能得到真正的源代码。
编译器(ccl):将高级语言翻译为机器语言。 - 以const或者enums替换#defines,避免遇到常量报错追溯困难。
-
常量指针的定义:
const char* p=“student”; //定义了一个指向string常量的指针 char* const p="student"; //定义了一个常量指针指向string const char* const p="student";//指针与所指对象均为常量
-
class专属常量:为了将常量的作用域限制于class内,使其成为class 的成员变量;若要保证该变量只具有一个实体,那么必须使其成为staic(静态成员变量)。静态成员变量遵循类内声明,类外初始化。但对于整数型的静态变量,可以在类内声明的同时进行初始化。
若是编译器不允许整数型的静态成员变量在class内进行初始化,可通过“the enum hack”进行枚举补偿做法。class mylist{ static const int data=0; public: int front; int last; mylist(const int&a,const int&b); };
-
无法通过#defines创建class的常量成员变量,不具有封装性,不存在private#define。
-
- 使用内联函数(inline)替换形似函数的宏
- 预处理器(.cpp):C++采用的是词法预处理器,主要进行文本替换,宏展开,删除注释这一类的简单工作。预处理器不进行语法检查,因为它不具备语法检查功能,并且预处理命令不属于C++语句。所谓预处理,是将程序中的宏展开,以及将头文件的内容包含进来,预处理不会生成文件,因此需要重新定向。经过预处理之后,才能得到真正的源代码。
- 尽可能多的使用const
- const作用域:class外部的全局或者命名空间中的常量,文件、函数或者区块作用域中的static对象,class内部的static以及non-static成员变量。遵循左物右针原则。
-
使用const修饰STL中的迭代器:迭代器的作用相当于指针T*。
-
将函数声明为const类型,避免错误的赋值操作。除非需要改动参数或者local对象,否则将函数参数也声明为const。
T* const iterator;//iterator指向的内存不变,但是内容是可变的。 const T* iterator;//iterator指向的内容不变,但是内存是可变的。 const std::vector<T>::iterator ite=vec.begin(); ite=vec.end();//错误 *ite=10;//正确 std::vector<T>::const_iterator::ite=vec.begin(); ite=vec.end();//正确 *ite=10;//错误 const int& add(const int &a,const int &b);
-
- const作用于类的成员函数:确定该成员函数可以作用于const对象。只有权限读取本次实例化对象*this的内容,而没有修改权限。
- 仅有常量性不同的成员函数,可以被重载。
- 真实程序中const对象多数用于传递指针常量或者传递引用常量。
- 如果函数的返回类型是内置类型,改动函数的返回值不合法。
- const成员函数不可以更改对象内任何非静态成员变量。若是要更改成员变量,首先通过mutable释放掉不可被const成员函数更改的约束。
- const与non-const成员函数的重复
-
常量性转除:先实现const成员函数,然后通过调用const成员函数来实现non-const成员函数的定义。
const char& operator[](std::size_t position) const; char & operator[](std::size_t position){ return const_cast<char &>(static_cast<const TextBlock>(*this} [position])//使用static_cast将*this指针转为const,使用const_cast移除返回值的const }
-
const成员函数调用non-const成员函数是错误做法。
-
- const作用域:class外部的全局或者命名空间中的常量,文件、函数或者区块作用域中的static对象,class内部的static以及non-static成员变量。遵循左物右针原则。
- 对象使用之前的初始化
-
内置类型必须手动初始化。
-
非内置类型的对象初始化通过构造函数完成,保证对象的每一个成员都被初始化。
对于类构造函数中成员的初始化,比进入构造函数函数体的时间更早,因此在函数体内发生的行为为赋值而非初始化。因此,类的构造函数最佳设计方式是使用初始化成员列表的方式。class A{ int first; int last; public: A(const int & a,const int & b){ first=a; last=b;} A(const int &a,const int& b):first(a),last(b){};//拷贝构造,效率更高,无须初值的直接default构造 };
-
成员初始化顺序:单个类中的成员初始化按照声明顺序初始化,多个类的顺序按照基类到派生类的顺序。
non-local-static对象初始化:除开函数内的static对象均为非局部静态对象。
对于不同文件中的non-local-static对象,其正确初始化次序c++并无明确规定,最常用的做法是将多个非局部静态对象整合到一个函数中定义,这样能保证首次遇上该对象定义时初始化。
补充知识点:
内联函数:inline,将代码副本放置到函数调用的地方。
内联函数最适用于小函数使用,例如访问私有数据成员。 这两行 “访问器” 函数的主要用途是返回有关对象的状态信息。 Short 函数对函数调用的开销很敏感。 更长的函数在调用和返回顺序中花费的时间更少,并且更少从内联中获益。// when_to_use_inline_functions.cpp class Point { public: // Define "accessor" functions as // reference types. unsigned& x(); unsigned& y(); private: unsigned _x; unsigned _y; }; inline unsigned& Point::x() { return _x; } inline unsigned& Point::y() { return _y; } int main() { }
inline 通常会节省的开销:函数调用(包括参数传递和在堆栈上放置对象地址)、保留调用者的堆栈帧、新建堆栈帧设置、返回值通信、还原旧的堆栈帧。
-
文章来源: blog.csdn.net,作者:tongchaun1999,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_39622197/article/details/116766735