关于C++中的前置声明

转载 2012年03月28日 23:13:32

今天一朋友问及C++中的前置声明问题,下面是我给出的回答。

 

在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration)。下面的程序中,带注释的那行就是类B的前置说明。这是必须的,因为类A中用到了类B,而类B的声明出现在类A的后面。如果没有类B的前置说明,下面的程序将不同通过编译,编译器将会给出类似缺少类型说明符这样的出错提示。

代码一:

// ForwardDeclaration.h

#include <iostream>

using namespace std;

 

class B;             // 这是前置声明(Forward declaration)

class A

{

private:

         B* b;

public:

         A(B* b):b(b)

         {

         }

         …

};

 

class B

{

         …

};

 

// Main.cpp

#include "ForwardDeclaration.h"

int main(int argc, char** argv)

{

         B* b = new B();

         A* a = new A(b);

 

         delete a;

         delete b;

 

         return 0;

}

上面程序可以顺利编译和运行(几乎没有做什么,也没有输出)

 

是不是有了前置说明就万事大吉了呢?我们看看下面的代码(带阴影部分的代码是新增加的)

代码二:

// ForwardDeclaration.h

#include <iostream>

using namespace std;

 

class B;             // 这是前置声明(Forward declaration)

 

class A

{

private:

         B* b;

public:

         A(B* b):b(b)

         {

         }

 

         void someMethod()

         {

                   b->someMethod();                                                  // (1)

         }

};

 

class B

{

private:

public:

         void someMethod()

         {

                   cout << "something happened..." << endl;

         }

};

 

// Main.cpp

#include "ForwardDeclaration.h"

 

int main(int argc, char** argv)

{

         B* b = new B();

         A* a = new A(b);

 

         a->someMethod();

 

         delete a;

         delete b;

 

         return 0;

}

 

一编译,发现代码(1)处出错。出错提示往往包括(不同的编译器给出的提示会有所不同)

1.       使用了未定义的类型B

2.       “->somemethod”的左边必须指向类/结构/联合/泛型类型

 

原因:

1.       (1)处使用了类型B的定义,因为调用了类B中的一个成员函数。前置声明class B;仅仅声明了有一个B这样的类型,而并没有给出相关的定义,类B的相关定义,是在类A后面出现的,因此出现了编译错误;

2.       代码一之所以能够通过编译,是因为其中仅仅用到B这个类型,并没有用到类B的定义。

 

解决办法是什么?

将类的声明和类的实现(即类的定义)分离。如下所示:

// ForwardDeclaration.h   类的声明

#include <iostream>

using namespace std;

 

class B;             // 这是前置声明(Forward declaration)

 

class A

{

private:

         B* b;

public:

         A(B* b);

         void someMethod();

};

 

class B

{

private:

public:

         void someMethod();

};

 

// ForwardDeclaration.cpp        类的实现

#include "ForwardDeclaration.h"

 

A::A(B* b):b(b)

{

}

 

void A::someMethod()

{

         b->someMethod();

}

 

 

void B::someMethod()

{

         cout << "something happened..." << endl;

}

 

// Main.cpp

#include "ForwardDeclaration.h"

 

int main(int argc, char** argv)

{

         B* b = new B();

         A* a = new A(b);

 

         a->someMethod();

 

         delete a;

         delete b;

 

         return 0;

}

 

结论:

前置声明只能作为指针或引用,不能定义类的对象,自然也就不能调用对象中的方法了。

 

而且需要注意,如果将类A的成员变量B* b;改写成B& b;的话,必须要将bA类的构造函数中,采用初始化列表的方式初始化,否则也会出错。关于这点,详见:特殊数据类型成员变量的初始化

C++模板类的前置声明

template class LinkedStack;templateclass Node{friend class LinkedStack;private: T data; Node *link;}...
  • fuli1215
  • fuli1215
  • 2011年04月13日 15:24
  • 5442

【C++学习与应用总结】2: 关于类型前置声明

本文总结了c++中前置声明的写法及注意事项,列举了哪些情况可以用前置声明来降低编译依赖。...
  • elloop
  • elloop
  • 2015年12月04日 07:51
  • 5351

【总结】C++前置声明

总结来说: 1)降低模块的耦合。因为隐藏了类的实现,被隐藏的类相当于原类不可见,对隐藏的类进行修改,不需要重新编译原类。 2)降低编译依赖,提高编译速度。指针的大小为(32位)或8(64位),X发...
  • qq_37660535
  • qq_37660535
  • 2017年06月09日 15:07
  • 129

C/C++前置声明和避免隐藏包含

1.C/C++.h文件中使用前置声明,减少大型项目的编译时间和支持相互包含。 判断使用前置声明的条件: 1)类指针/类引用数据成员,静态的类对象可以使用前置声明,函数参数/返回值的类型声明为类对象。 ...
  • Blues1021
  • Blues1021
  • 2015年04月10日 20:24
  • 623

带命名空间的类的前置声明

A.h #pragma once namespace TEST { class A { public: A(void) { } virtual ~A(void) ...
  • zhong_sheng_
  • zhong_sheng_
  • 2014年07月05日 18:07
  • 1203

c++中 如何前置声明一个名称空间中的类

//file A.h namespace A { class ClassA { }; }; //file B.h namespace A{ class C...
  • u014053368
  • u014053368
  • 2014年04月13日 13:19
  • 290

c++之类的前置声明

        原创文章,转载请注明出处,谢谢!               作者:清林,博客名:飞空静渡 刚开始学习c++的人都会遇到这样的问题:定义一个类 class A,这个类里面使用了类B的对...
  • fjb2080
  • fjb2080
  • 2010年04月27日 12:36
  • 5316

c++中namespace和前置声明

前置声明一般用于要在一个类中使用另一个类,而另一个类的声明在后面或者其他文件中时 如类A和B class A{ private:       B *b; }; class B{ };这里类B在类A后...
  • hhm853610070
  • hhm853610070
  • 2017年03月20日 15:59
  • 869

C++中如何设置前置声明

转载自 http://www.cnblogs.com/alaigle/archive/2012/06/05/2536610.html在编写C++程序的时候,偶尔需要用到前置声明(Forward dec...
  • u010339647
  • u010339647
  • 2017年09月05日 14:53
  • 137

std::vector的前置声明

待续
  • yaofahua
  • yaofahua
  • 2014年08月21日 09:09
  • 329
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于C++中的前置声明
举报原因:
原因补充:

(最多只允许输入30个字)