http://blog.sina.com.cn/s/blog_6fc5bfa90100oaum.html
看了C++ Primer 感觉真的不太好理解,反正我是不好理解,还是买一本Primer Plus 吧。
P59页说:
头文件用于声明而不是用于定义
当设计头文件时,记住定义和声明的区别是很重要的。定义只可以出现一次,而声明则可以出现多次(第 2.3.5 节)。下列语句是一些定义,所以不应该放在头文件里:
extern int ival = 10; // initializer, so it's a definition
double fica_rate; // no extern, so it's a definition
虽然 ival 声明为 extern,但是它有初始化式,代表这条语句是一个定义。类似地,fica_rate 的声明虽然没有初始化式,但也是一个定义,因为没有关键字 extern。同一个程序中有两个以上文件含有上述任一个定义都会导致多重定义链接错误。
因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。
对于头文件不应该含有定义这一规则,有三个例外。头文件可以定义类、值在编译时就已知道的 const 对象和 inline 函数(第 7.6 节介绍 inline 函数)。这些实体可在多个源文件中定义,只要每个源文件中的定义是相同的。
在头文件中定义这些实体,是因为编译器需要它们的定义(不只是声明)来产生代码。例如:为了产生能定义或使用类的对象的代码,编译器需要知道组成该类型的数据成员。同样还需要知道能够在这些对象上执行的操作。类定义提供所需要的信息。在头文件中定义 const 对象则需要更多的解释。
以上所说的声明是指单独的声明,而不是在类里面声明,类本身就是一个声明,其他的声明是单独的声明,而不是类里面的声明。
// head.h
#include
using std::cout
...
extern int x;// Ok
int y;// error 不能在这里定义
extern int z = 9;// error 不能在这里定义
class DDD
{
public:
...
private:
extern int a ;//error 错误的,不能在这里写,要写在类的外面
int b; // Ok
};
extern 是定义外部变量,可以几个文件共享,但是只能定义一次
如一个工程里
//mod.h
#include
using std::cout;
using std::cin;
using std::endl;
extern int x;
void add( );
void dec( );
class mod
{
public:
mod( );
void inbase( );
void inexp( );
int smod( );
void output( );
~mod( );
private:
int base;
int exponent;
};
//mod.cpp
#include "mod.h"
mod::mod( )
{
base = 1;
exponent = 1;
}
void mod::inbase( )
{
cout << "Please enter the base number:\n ";
cin >> base;
}
void mod::inexp( )
{
cout << "Please enter the exponent number: \n";
cin >> exponent;
}
int mod::smod( )
{
int sum = 1;
if( exponent == 0 )
sum = 1;
else
{
for( int i = 0; i != exponent; ++i )
{
sum *= base;
}
}
return sum;
}
void mod::output()
{
cout << "the sum of " << base << " and exponent " << exponent << " is : " << smod() << endl;
}
mod::~mod()
{
}
// test1.cpp
#include "mod.h"
void add()
{
x += 8;
}
//test2.cpp
#include "mod.h"
void dec()
{
x -= 4;
}
//test.cpp
#include "mod.h"
#include
using std::cout;
using std::endl;
int x = 5;
int main()
{
cout << x << endl;
add();
cout << x << endl;
dec();
cout << x << endl;
return 0;
}