terms 1 : View C++ as a federation of language
视C++为一个语言联邦
C++是一个多重泛型编程语言(Multiparadigm programming language), 支持过程形式(procedural),面向对象形式(object-oriented),函数形式(functional),泛型形式(generic),元编程形式(metaprogramming)。
过程形式也就是面向过程编程,对函数的复用,实物的抽象几乎没有,根据问题的解题思路一步步编程以解决问题,我们刚开始学习第一门编程语言,大部分就是从面向过程进行编程。
面向对向形式也就是对要处理的事情或某些事物进行抽象处理,笔者在刚接触面向对象这一概念时最先联想到的是界门纲目科属种,也就是说提取事物特征进行分门别类,界门纲目科属种之下还有更细节的划分,也就是继承。
函数形式也就是代码复用,将某些经常用到的功能写成函数,每次使用调用方法函数即可,c++语言有众多可供调用的函数库,这也是c++代码风靡的一个重要原因,很多热门编程语言都具有丰富的自带库以及第三方库,像python等。
泛型形式和元编程,这两个概念读者并不是很清楚,我个人认为就是C++的模板元编程。
terms 2 : Prefer consts,enums,and inlines to #defines
尽量使用consts enums inlines 代替 #defines
也就是说尽量用常量,枚举量,内联代替使用宏定义,宏定义是一种定义替换,当使用一些复杂的宏定义时,由于替换特性往往招致意想不到的错误(虽然我觉得大多数程序员并不会写这种代码,但是这种代码确实符合语法规范,这时候可以选择内联函数替换宏),另外,宏定义的内容不被编译器所见,#开头代表预处理命令,也就是发生错误后,你看到的不是定义的宏名,而是宏值,这对于程序调试很不友好。此外,宏定义不重视作用域,但是定义的变量却有作用域。
一个秒语法:使用enum hack替换静态常量 ,enum hack(模板元编程的基础技术)(笔者也不懂,但是记着语法知道意思还是没问题)
terms 3 : Use const whenever possible
尽可能使用const
const的作用于指针的四种形式
char* p; //指针指向可变,可通过指针改变所指对象值
const char* p; //可改变指针指向,补课通过指针改变所指对象的值
char* const p; //不可改变指针指向,可通过指针改变所指对象的值
const char* const p;//不可改变指针指向,不可通过指针改变所指对象的值
const 在星号之前表示表示所指对象为常量,也就是不能通过指针改变所指对象的值,而const在“*”之后表示指针是常量,不能改变指针指向。
当函数返回一个const对象
当我们进行面向对象编程并重载操作符时,我们经常会返回一个常量对象,例如重载“*”,我们理所应当的使用 a = b * c ,但是当我们返回一个非常量对象时,b * c = a 的语法也是正确的。
改变一个常量对象的值
常量值不可改变,但是有些时候我们却可以改变一个常量对象的值
#include <iostream>
using namespace std;
class CtextBlock{
public:
CtextBlock(){
pText=new char[10*sizeof(char)];
pText[0]='h';
pText[1]='e';
pText[2]='l';
pText[3]='l';
pText[4]='o';
}
void show()const { //常量函数只能由常量对象调用
cout<<pText<<endl;
}
char& operator[](std::size_t position) const {
return pText[position];
}
private:
char *pText;
};
int main()
{
const CtextBlock ct;
ct.show();
char *p=&ct[0];
*p='J';
ct.show();
cout << "Hello World!" << endl;
return 0;
}
const成员函数返回了一个引用,通过此引用我们可以改变成员变量的值。此时我们可以将返回值设置为const避免此种意想不到的结果。
const成员函数
三句话:
- const函数只能由常量对象调用
- const成员变量只能由初始化列表进行初始化
- const成员函数可以查看成员变量的值,但是不能修改值
让const成员函数修改成员变量的值
上面三句真理中第三局句,const成员函数不能修改成员变量的值,但是C++也提供了可以修改的方法,也就是用mutable修饰,下面有一个例子
#include <iostream>
using namespace std;
class Student{
public:
//const成员变量只能由初始化列表进行初始化
Student(int num1,int num2,int num3):number(num1){
this->number2=num2;
this->number3=num3;
}
//非const成员函数
void show(){
cout<<"非const成员函数"<<endl;
cout<<"number :"<<number<<endl;
cout<<"number2:"<<number2<<endl;
cout<<"number3:"<<number3<<endl;
}
//const成员函数 const成员函数不能修改成员变量
void show() const{
cout<<"const成员函数"<<endl;
//由mutable修饰的成员变量可以释放bitwise constness
cout<<"number3修改前:"<<number3<<"\n修改后:"<<endl;
number3=5;
cout<<"number :"<<number<<endl;
cout<<"number2:"<<number2<<endl;
cout<<"number3:"<<number3<<endl;
}
private:
const int number;
int number2;
mutable int number3;
};
int main()
{
const Student s1(1,2,3);
Student s2(2,3,4);
s1.show();
s2.show();
cout << "Hello World!" << endl;
return 0;
}
#include <iostream>
using namespace std;
class Student{
public:
//const成员变量只能由初始化列表进行初始化
Student(int num1,int num2,int num3):number(num1){
this->number2=num2;
this->number3=num3;
}
//非const成员函数
void show(){
cout<<"非const成员函数"<<endl;
cout<<"number :"<<number<<endl;
cout<<"number2:"<<number2<<endl;
cout<<"number3:"<<number3<<endl;
}
//const成员函数 const成员函数不能修改成员变量
void show() const{
cout<<"const成员函数"<<endl;
//由mutable修饰的成员变量可以释放bitwise constness
cout<<"number3修改前:"<<number3<<"\n修改后:"<<endl;
number3=5;
cout<<"number :"<<number<<endl;
cout<<"number2:"<<number2<<endl;
cout<<"number3:"<<number3<<endl;
}
private:
const int number;
int number2;
mutable int number3;
};
int main()
{
const Student s1(1,2,3);
Student s2(2,3,4);
s1.show();
s2.show();
cout << "Hello World!" << endl;
return 0;
}