• 讨论一下定义和声明的区别


        C++primer的解释是这样的:

        变量的定义(definition):用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义;

        变量的声明(declaration):用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。

        以上解释讲得还是比较清楚的,有分配空间的叫定义,没分配空间的叫声明。好吧,你不知道什么时候分配什么时候没分配。让我们换一种说法。

        “定义也是声明”,这说明声明包括定义。所以诸如int a;extern int a;之类的一定是声明。那是不是定义还要接着往下看;

        如果程序前面都没有出现过a这个变量,这时你要使用a,你必须让程序知道你要使用a这个变量了。这时候你写入int a;以前没有a这个变量的,现在程序为了记住它,就得为他分配空间,于是这是个定义。

        如果程序包含的其他文件里已经出现过a了,这证明程序已经为a分配内存,这时你要使用a就方便很多了。你只需要告诉程序,这个a在其他地方定义过了,于是你写入extern int a;

        对于int a;来说,它既是定义又是声明;对于extern int a;来说,它是声明不是定义。一般为了叙述方便,把建立存储空间的声明称定义,而不把建立存储空间的声明称为声明.

    [引申阅读]探讨下c++的声明和定义问题,关于extern

    c++primer第四版中,53页的习题2.18中问到,extern std::string name;是属于声明还是定义?答案说的是声明。不过我认为,string类中有默认构造函数,如果该语句在函数外,那么则会自动获得储存空间,将name定义为空字符串,不知各位有何高见?

    问题补充:

    感谢回答我的关于extern的问题,可是还是没想通。正如一楼举的例子extern std:tring name("Zhang3Li4");我认为extern std::string name;和那句是一样的 .因为标准库中的string是有默认构造函数的,若后面什么都没有的话,就初始为空字符串

    ------

    我刚才做了一个实验:
    //a.cpp 
    #include <string>

    std::string i;

    //b.cpp
    #include <iostream>
    #include <string>

    extern std::string i;

    int main ()
    {
    std::cout << i << std::endl;
    }

    运行结果为:

    (上面是一空行:由于末尾用了endl)

    如果没有a.cpp这个文件,运行出错
    这是一对实验(有没有a.cpp文件)

    可得出这样的结论:
    a.cpp中std::string i;是定义(本来就是)
    b.cpp中extern std::string i; 则是声明(你的问题)

    先别急,这只是实验结果。我们还需要理论依据,那么下面就试着解释一下:

    下面是另一个例子(也是第二个实验)
    你应该知道内置类型(int等)如果作为全局变量时,定义的同时也就初始化了(一个内置类型有其对应的默认值;如果你将自定义类型也看成内置类型,那么就等于说,一个自定义类型有其对应的默认值(由默认构造函数完成))。如
    //c.cpp
    int i;

    //d.cpp
    #include <iostream>

    extern int i;

    int main ()
    {
    std::cout << i << std::endl;
    }

    那么在这里int i; 就是定义(并且初始化了i,初始值为0)
    因而输出结果为
    0
    //这个实验的运行结果符合理论依据。
    (我使用的编译器是visual studio 2008)


    从这两个实验来看:(将两个“默认”等同起来)
    int i;
    std::string i;
    都可以作为初始化i的定义性语句。
    那么
    extern int i;
    extern std::string i; 
    也具有定义行为(这个很明显与extern的用法相悖)

    在以上两个试验中:int 与 string 有“区别”吗?所有的代码都一样只不过把std::string 换成了 int而已!如果你能解释int的情况,那么我想std::string问题也就迎刃而解了!

    于是我个人总结出一个结论:
        不论是内置类型还是自定义类型,前面有extern关键字,如果没有显式地初始化参数(即就是自定义类型的默认构造函数被extern屏蔽了,不起初始化的作用),那么就按声明对待。

    可能我的描述很混乱,希望你好好看看上面的例子,就明白了! 
    注意:从这里可以看出来默认构造函数的特殊性

  • 相关阅读:
    谈谈JavaScript中继承方式
    《前端架构设计》学习笔记一--架构的种子
    正则中1的用法---反向引用
    JavaScript千分符---正则实现
    JavaScript开发中常用的代码规范配置文件
    前端开发流程---我们应该做些什么
    JavaScript中数据类型判断
    冒泡排序以及改进
    Number和toString中的坑
    Fluent Ribbon 第五步 ToolBar
  • 原文地址:https://www.cnblogs.com/iloveyoucc/p/2411749.html
Copyright © 2020-2023  润新知