C++中声明和定义的区别2

来源:互联网 发布:浙江省麻醉质量数据库 编辑:程序博客网 时间:2024/06/07 21:40
 

CSDN里用人问:

我一直以为定义=声明+初始化,即int i;是声明,int i =0;是定义。
但看侯捷翻译的Effective C++上面说string ps;也是个定义(在条款定义应该尽量靠后的那节),如果定义过早,就会过早引入构造的负担。
难道我对声明和定义的概念一直有错吗
声明不导致内存分配,那么到底如何区分定义和声明?

我在楼下回帖里挑选了几个比较靠谱的答案进行了一下总结,以防以后自己也忘了。

"声明"的严谨C++语意,是用以告诉编译器类型及其细节,例如:

class MyClass
{
  //数据成员细节...
  //成员函数细节...
};

上述声明仅告诉编译器有自定义类型MyClass,编译器仅对其进行语汇分析及名字的决议,并未占用内存!

"定义"的严谨C++语意,即内存占有,编译器将在相对内存地址上为其对象定址!

要注意的是,我们不能简单的说

string myString;  

是声明还是定义,判断的原则是看是否占用内存。例如:

class MyClass //类的声明,无内存占有{  string myString; //string的声明};

但是

#include<iostream>
 
//全局作用域
string myString;//定义,myString是实例化的string!
 
int main()
{
  //Main函数体内
  string myAnotherString;//定义,myAnotherString是实例化的string!
  return 0;
}

所以有回复说:

变量和对象不加extern永远是定义,类中的除外。
函数只有函数头是声明,有函数体的是定义。
类永远只是声明。类成员函数的函数体是定义。

class MyClass
{
    static int x; //这里的x是声明
    static const int a; //这里的a是声明
    //非static变量在类实例化时才分配内存.
    MyClass();//这里的函数是声明
};
int MyClass::x;//这是定义
const int MyClass::a=11;//这是定义

 

注:

声明一个变量只是将变量名标识符的有关信息告诉编译器,使编译器“认识”该标识符,但是声明并不一定引起内存的分配。而定义一个变量意味着给变量分配内存空间,用于存放对应类型的数据,变量名就是对相应内存单元的命名。在C++程序中,大多数情况下变量声明也就是变量定义,声明变量的同时也就完成了变量的定义,只有声明外部变量时例外。在定义一个变量的同时,也可以给它赋以初值,而这实质上就是给对应的内存单元赋值。

所以说 定义 不等于 声明+ 初始化

因为 定义一个变量就意味着给变量分配内存空间,而初始化只是在分配内存空间的这地址上存入一个值,所以说初始化是一个“存入”值的动作,不是分配内存空间的动作,尽管存入值需要先分配内存空间, 但是不要把存入值 等同于 分配内存空间!即:声明是告诉编译器变量名标识符的信息,不分配内存, 定义是给变量分配存在空间,不需要负责赋初值, 初始化则是给已经指定的内存空间存入初值,这三者的动作一个是“告诉”,一个是“分配” 一个是“存入”,是不同滴。

 打个形象点的比喻:办银行卡

去银行办金卡首先需要告诉为你办金卡的工作人员你的身份证信息,然后工作人员根据你的信息在他们的银行系统上给你登记信息,留出一个数据库表格来记录你的信息和资金情况,办完后发给你一张金卡,现在你有了金卡是吧,你就会往里面存钱啊,你总不会办个金卡不用吧?

分析如下

 

"告诉为你办金卡的工作人员你的身份证信息" 就相当于变量声明, 即把变量标识符相关信息("你身份证等标识你个人的相关信息")告诉给编译器("工作人员")

 

"工作人员根据你的信息在他们的银行系统上给你登记信息,留出一个数据库表格来记录你的信息和资金情况"就相当于变量定义,即给变量("就是标识你这个人的变量")分配内存空间("在他们的银行系统上分配一个专门存在你资金信息和个人信息的数据库表")

 

"往金卡里面存入现金"就相当于初始化,即对标识你个人身份的那张金卡所对应的数据库中写入你存储的金额(就相当于给指定的变量赋初值),你总不会把钱存到别人的卡上吧?

 

根据上面的案例来深入分析下面三句话:

1.声明不等于定义,因为声明不分配内存,定义会分配内存

2.变量声明也就是变量定义,因为声明变量的同时也就完成了变量的定义

3.定义 不等于  声明+初始化

 

分析第一句:你去办金卡,提交个人子类给工作人员审核正确才能办,所以"告诉为你办金卡的工作人员你的身份证信息"是相当于告诉编译器你这个变量的信息, 但是他还并没有给你开帐号,所以只是声明,还没有分配内存,不可能只要提交个人身份证信息就开户了吧 ,难道不管什么是不是假证?当然是真的是你的身份证就会给你开户了,也就是定义了,所以你给他你的个人信息就是声明的过程, 至于人家审核之后是否开户跟声明这个过程不搭边了,因为你给了他你的信息之后 就相当于声明就完了, 之后的事就不属于声明的范畴了,从你拿出个人信息开始就代表着声明的开始, 当你把个人信息给了工作人员就代表着声明的结束!

 

分析第二句:你说吧 你要去银行办金卡一般情况不可能拿假身份证信息给人家吧, 所以你去开户拿给人家工作人员看的信息肯定是真实的,那么你本来就是要来开户的,现在工作人员审核你的信息是真实的当然也就立刻为你开户了,工作人员不可能说“你的信息我们已经审核为真实资料通过,但是请你明天再来办理。”如果是这样估计你非把工作人员打爆不可吧, 呵呵呵, 所以你看这里分提供信息和开户无时间间隔一起完成了,所以就有了说"变量声明也就是变量定义,因为声明变量的同时也就完成了变量的定义"

 

分析第三句:定义 不等于声明+初始化 这个很好理解啦, 你说你去银行办金卡,不可能是你向银行提交个人信息 再交一打钱 人家就给你发个金卡吧? 难道你的个人信息不要审核?就算审核通过 ,人家也要有点时间来在他的电脑上给你填写相关信息,分配存在你信息的数据表什么的吧,那这个跟你提交个人信息和一打钱没啥关系啊,但是这个“他的电脑上给你填写相关信息,分配存在你信息的数据表”就是“定义”的意思啊

 

有些人要说了,我本来没有金卡,那我把个人信息和一打钱一起给工作人员 ,人家是发了一个金卡给我而且把钱存入了啊, 是的, 可是定义的时候也可以赋初值的啊!

可是赋初值并不等于定义啊, 比如你上午刚在中国银行办的金卡, 完了 你下午去工商银行提交工人信息和一打钱, 人家也有可能(信息真实的情况下)发你一张金卡但是此金卡非中国银行的那张金卡啊,你的钱存入到另一个地方了啊

 

到底是怎么区分呢?还望高手解答。