Thinking in C++前几章笔记(1)

家住魔仙堡 提交于 2020-01-28 15:49:02

Thinking in C++前几章笔记

1、对象:把问题空间中的事物和它们在解空间中表示行为称为对象。

万物皆对象,程序就是一组对象,对象之间通过发送消息互相通知做什么。创建抽象数据类型是面向对象程序设计的基本思想。所以程序设计中,所做的工作就是创造新的数据类型。而面向对象程序设计的难题之一,是在问题空间中的元素和解空间的对象之间建立一对一的映射。

2、代码重用是面向对象程序设计语言的最大优点之一。重用一个类最简单的方法就是直接使用这个类的对象,我们常称为组合(has a)。而继承(基类和派生类)是is a的关系。

3、我们把处理派生类型如同处理其基类型的过程称为向上类型转换(upcasting)。

4、理想的类应当一目了然。运行进行可能是OOP最主要的好处。引入一个库,就是在向该语言引入一个新的类型。

5、极限编程(XP,eXtreme Programming):先写测试;结对编程(两个人)。

8、asm关键字

这是一种转义(escape)机制,允许在C++程序中写汇编代码。

9、调试技巧

1)使用预处理调试标记

#define DEBUG

//...

#ifdef BEBUG

//debugging code here

#endif//DEBUG

2)把变量和表达式转换成字符串

   在一个预处理器宏中的参数前面使用一个#,预处理器会把这个参数转换为一个字符数组。(原文:When you put a # before an argument in a preprocessor 

macro, the preprocessor turns that argument into a character array. This, 

combined with the fact that character arrays with no intervening punctuation 

are concatenated into a single character array, allows you to make a very 

convenient macro for printing the values of variables during debugging)

#include "iostream"

using namespace std;

#define P(A) cout<<#A<<": "<<(A)<<endl;

int main()

{

int a=1,b=2;

P(a);

P(b);

P(a+b);

return 1;

}

下图中下面的那个结果窗口,可以看到,#A输出了变量名,而A仅仅是输出了这是值。

3)assert()宏

   预处理器产生测试该断言的代码。使用assert()时,给一个参数,即一个表示为真的表达式。如果表达式不为真,则会有断言的相应处理。

(原文: When you use assert( ), you give it an argument that is an expression 

you are “asserting to be true.” The preprocessor generates code that will test 

the assertion. If the assertion isn’t true, the program will stop after issuing an 

error message telling you what the assertion was and that it failed. )

#include "iostream"

#include "cassert"

using namespace std;

int main()

{

int i=1001;

assert(i!=1001);//falls

return 1;

}

   When you are finished debugging, you can remove the code generated by 

the macro by placing the line:

 #define NDEBUG

in the program before the inclusion of <cassert>, or by defining NDEBUG on 

the compiler command line. NDEBUG is a flag used in <cassert> to change 

the way code is generated by the macros.

#include "iostream"

#define NDEBUG

#include "cassert"

//.......

10、指向函数的指针数组

One of the more interesting constructs you can create is an array of 

pointers to functions. To select a function, you just index into the array and 

dereference the pointer. This supports the concept of table-driven code(表格式

驱动码); instead of using conditionals or case statements, you select functions 

to execute based on a state variable (or a combination of state variables). This 

kind of design can be useful if you often add or delete functions from the table 

(or if you want to create or change such a table dynamically).

#include "iostream"

using namespace std;

#define DF(N) void N() { cout << "function " #N " called..." << 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()

{

a();

while(1)

{

cout<<"press a key from 'a' to 'g' or q to quit"<<endl;

char c,cr;

cin.get(c);

cin.get(cr);//吸取回车符

if(c=='q')

 break;

if(c<'a'||c>'g')

 continue;

(*func_table[c-'a'])();

}//while

return 1;

}

11、在C++中,头文件的使用非常明显:放入声明。C++的一个规则:可以对事物声明多次,但是只能定义一次。C/C++都允许重声明函数,只要两个声明匹配即可。但是两者都不允许重声明结构。

12、预处理指示#define,#ifdefine,#endif

#define FLAG

//...

#ifdef FLAG

//...

#endif //FLAG

#define的反意是#undef

#ifdef的反意是#ifndef

对于包含结构的每个头文件,应当首先首先检查这个头文件是否已经包含在特定的CPP文件中了。通过测试预处理器的标记来检查。

#ifndef HEADER_FLAG

#define HEADER_FLAG

//declaration here...

#endif

These preprocessor statements that prevent multiple inclusion are often 

referred to as include guards.

13、句柄类

   在头文件中包含声明。However, including the private implementation has 

two effects: the implementation is visible even if you can’t easily access it, and 

it can cause needless recompilation.

An included header file – is touched. This means that any time you make 

a change to a class, whether it’s to the public interface or to the private 

member declarations, you’ll force a recompilation of anything that includes 

that header file. This is often referred to as the fragile base-class problem. 

解决方法称为句柄类(handle class)或称为Cheshire cat。示例如下:

   //: C05:Handle.h

// Handle classes

#ifndef HANDLE_H

#define HANDLE_H

class Handle {

  struct Cheshire; // Class declaration only

  Cheshire* smile;

public:

  void initialize();

  void cleanup();

  int read();

  void change(int);

};

#endif // HANDLE_H ///:~

//: C05:Handle.cpp {O}

// Handle implementation

#include "Handle.h"

// Define Handle's implementation:

struct Handle::Cheshire {

  int i;

};

void Handle::initialize() {

  smile = new Cheshire;

  smile->i = 0;

}

void Handle::cleanup() {

  delete smile;

}

int Handle::read() {

  return smile->i;

}

void Handle::change(int x) {

  smile->i = x;

} ///:~

 

14、小作用域是良好设计的指标。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!