c++中的前置声明

    添加时间:2013-7-19 点击量:

    引用google c++编码规范:



    When you include a header file you introduce a dependency that will cause your code to be recompiled whenever
    the header file changes. If your header file includes other header files, any change to those files will cause any code
    that includes your header to be recompiled. Therefore, we prefer to minimize includes, particularly includes of header
    files in other header files.





    include一个头文件,就多了一种依附,当头文件产生变更时,须要从头编译,是以尽量罕用include,尤其是在头文件中包含头文件的景象下。


    前置声明感化:削减include;解决轮回依附的题目。


    如下,两个类中互包含了类对象成员,产生轮回依附。


    class Barney{ Fred x;  };

    class Fred{ Barney y;};


    在应用一个类之前,必须先定义该类。应用前置声明,在引用不决义的类之前,将该类的名字告诉编译器,使编译器知道那是一个类名。


    然则供给完全类定义之前,不克不及定义该类的对象,也不克不及在内联成员函数中应用该类的对象。


    前置声明应用错误景象1、


    class Fred;


    class Barney{ Fred x;  //error C2079: “Barney::x”应用不决义的 class“Fred”  };


    class Fred {  Barney y; };


     前置声明应用错误景象2、


    class Fred;
    class Barney
    {


    public: void method(){ x->dosomething(); //error C2227: “->dosomething”的左边必须指向类/布局/结合/泛型类型 }
    private: Fred x;
    };

    class Fred
    {
    public: void dosomething(){};


    private:  Barney y;
    };


    如上景象解决的办法是,批改两个类的定义次序,或者将dosomething改为非内联函数。


    class Fred2;


    class Barney2


    {


    public:   void method();


    private:     Fred2 x;


    };


    class Fred2


    {


    public:    void dosomething(){};


    private:     Barney2 y;


    };


    //改成非内联函数,在Fred2完全定义后在给出函数定义,或者更改两个类定义的次序。


    void Barney2::method() {  x->dosomething(); }



    综上,应用前置声明可以解决轮回包含,和include的项目组题目。别的要避免互相定义应用类对象的景象。google编码规范中也给出了在头文件中应用前置声明的重视事项:



    How can we use a class Foo in a header file without access to its definition?







    • We can declare data members of type Foo or Foo&.





    • We can declare (but not define) functions with arguments, and/or return values, of type Foo. (One exception is if an argument Foo or const Foo& has a non-explicit, one-argument constructor, in which case we need the full definition to support automatic type conversion.)





    • We can declare static data members of type Foo. This is because static data members are defined outsidethe class definition.







    关键,区分下声明和定义。



    真正的心灵世界会告诉你根本看不见的东西,这东西需要你付出思想和灵魂的劳动去获取,然后它会照亮你的生命,永远照亮你的生命。——王安忆《小说家的十三堂课》
    分享到: