读书笔记:
10.1 头文件与源文件的区别?
(1).cpp文件主要包含确定程序做什么的代码,它们由函数定义组成;
(2).h文件包含函数声明、内联函数定义,枚举和自己的类型定义,以及预处理指令,尽量避免在头文件中定义函数。
10.2 程序中的每个实体都只能有一个定义:
(1)在转换单元(它是添加了所有包含都文件内容的.cpp文件)中,每个不是局部块作用域的变量、函数、类类型、枚举型或模板都只能定义一次;
10.3 名称的链接属性?
(1)内部链接属性:该名称表示的实体可以在同一个转换单元的任何地方访问;(如全局作用域定义的、声明为const的变量名默认具有内部链接属性);
(2)外部链接属性:除了可以在它的转换单元中访问外,还可以在另一个转换单元中访问;(如所有函数以及全局作用域定义的非const变量都具有外部链接属性)
(3)没有链接属性:实体只能应用于该名称的作用域中访问。(在块中定义的所有名称,即局部名称没有链接属性)
Tips:变量名不同于函数名,某变量名定义对于当前转换单元是外部的,如果需要访问,则需要用extern关键字来声明该变量
Tips:迫使声明为const的全局变量名具有外部链接属性,则在定义这些变量时,前面加上extern即可,其他转换单元访问也需要加上extern;
10.4 命名空间?
(1)命名空间是一个区域,该区域把一个额外的名称附加到该区域的所有实体上。(两个不同命名空间可以包含名称相同的实体,但他们是不同的,以解决命名冲突的情况)
(2)定义命名空间 namespacemyRegion{ } (注:命名空间定义的最后没有分号)
(3)一个命名空间可以由几个独立的同名命名空间声明组成;
(4)为了在命名空间的外部引用在命名空间中声明的标识符,需要指定命名空间的名称和标识符,两者之间用作用域解析符::分开;
(5)未命名空间不在全局命名空间中,未指定名称的命名空间在转换单元是唯一的;(未命名空间声明的函数和变量及其他实体都是它们转换单元的本地成员)
(6)命名空间内部可以嵌套定义另一个命名空间;
10.5 预处理器?
(1)预处理器执行预处理指令,在编译代码之前传送转换单元中的源代码。处理完所有的指令后,转换单元就只包含C++代码,没有之前的预处理器指令了;
(2)可以使用条件预处理器指令,确保头文件的内容在一个转换单元中没有重复;
(3)可以使用条件预处理器指令,控制是否在程序中包含跟踪或其他诊断调试代码;
10.6 头文件?
标准库文件名放在尖括号内(如<iostream>),自己头文件放在双引号内(如"my.h");
10.7 #define指令的三个主要的缺点:
(1)#define指令不支持类型的检查;(尽量使用内联函数或函数模板,这样检查函数的参数类型,减少错误)
(2)#define指令不考虑作用域;
(3)符号名不能限制在一个命名空间中;
10.8 assert( )宏允许在执行过程中测试逻辑条件,如果条件为假,就输出一个消息,并终止程序;
习题参考解答(自编):
10-1、10-2:把文件组织成一个工程
//main.cpp
#include "print.h"
extern int count_print;
int main()
{
//10-1 output
print_this("print_this function test");
print_that("print_that function test");
print("print function test");
//10-2 output
cout<< endl << "count_print = " << count_print <<endl;
return 0;
}
//print.cpp
#include "print.h"
using std::cout;
using std::endl;
int count_print = 0;
void print(const string& s){
cout<< s <<endl;
count_print++;
}
//print_this.cpp
#include "print_this.h"
void print_this(const string& s){
print(s);
}
//print_that.cpp
#include "print_that.h"
void print_that(const string& s){
print(s);
}
//print.h
#if !defined print_h
#define print_h
#include <iostream>
#include <string>
#include "print_this.h"
#include "print_that.h"
using std::string;
void print(const string& s);
#endif
//print_this.h
#if !defined print_this_h
#define print_this_h
#include "print.h"
using namespace std;
void print_this(const string& s);
#endif
//print_that.h
#if !defined print_that_h
#define print_that_h
#include "print.h"
using std::string;
void print_that(const string& s);
#endif
10-3、10-4: 10-4没有单独写一个工程,也没有按照题意来写,仅仅参考吧
//main.cpp
#include "print.h"
//#define DO_THIS
int main()
{
//10-3 output
cout<< "10-3 test as follow:" <<endl;
print_this("print_this function test");
print_that("print_that function test");
cout<< endl <<"10-4 test as follow:" <<endl;
#ifdef DO_THIS
PRINT("abc_this");
#else
PRINT("abc_that");
#endif
return 0;
}
//print.cpp
#include "print.h"
using std::cout;
using std::endl;
void print1::print(const string& s){
cout<< "use print1 to print" <<endl;
cout<< s <<endl;
}
void print2::print(const string& s){
cout<< "use print2 to print" <<endl;
cout<< s <<endl;
}
//print.h
#if !defined print_h
#define print_h
#include <iostream>
#include <string>
#include "print_this.h"
#include "print_that.h"
#define PRINT(abc) cout<< abc <<endl
using std::string;
namespace print1{
void print(const string& s);
}
namespace print2{
void print(const string& s);
}
#endif
//print_this.cpp
#include "print_this.h"
#include "print.h"
void print_this(const string& s){
print1::print(s);
}
//print_that.cpp
#include "print_that.h"
#include "print.h"
void print_that(const string& s){
print2::print(s);
}
//print_that.h
#if !defined print_that_h
#define print_that_h
#include "print.h"
using namespace std;
void print_that(const string& s);
#endif
//print_this.h
#if !defined print_this_h
#define print_this_h
#include "print.h"
using namespace std;
void print_this(const string& s);
#endif