【转载】C++中的前向声明

整理于:
http://blog.csdn.net/heyutao007/article/details/6649741
http://blog.sina.com.cn/s/blog_68d90fdb0100yapr.html

  1. 前向声明好处
    1)不必要的#include 会增加编译时间.
    2)混乱随意的#include可能导致循环#include,可能出现编译错误.

  2. 定义
    可以声明一个类而不定义它。这个声明,有时候被称为前向声明(forward declaration)。比如class Screen; 在声明之后,定义之前,类Screen是一个不完全类型(incompete type),即已知Screen是一个类型,但不知道包含哪些成员,具有哪些操作。不完全类型只能以有限方式使用,不能定义该类型的对象,不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。
    类的前向声明只适用于指针和引用的定义,如果是普通类类型就得使用include了。

class A;   
class B   
{   
public:   
	A* m_a; //(不能A m_a)
	static A m_a2;//这个是可以的,因为静态成员变量不占用类对象的大小,是存在静态区的,所以不影响,记住:目的是c++编译器可以确定对象的大小   
};
  1. 前向声明的限制
    (1)不能定义foo类的对象;
    (2)可以用于定义指向这个类型的指针或引用。(很有价值的东西);
    (3)用于声明(不是定义)使用该类型作为形参或者返回类型的函数。4

  2. 实例
    c++编译器做的事情主要是:1.扫描符号;2.确定对象大小。
    所以很多时候并不需要将类都include进来。
    比如:
    (1)由于所有对象类型的引用所占用的空间都是相同大的,所以c++编译器很好确认对象大小(引用的大小???)。

class String;  
class Sample  
{  
private:  
	String &s;  
};

这里只需要做一个string的前向声明就可以了,不需要#include

(2)由于所有类型的指针也是相同大小的。所以与(1)类似,也可以只做前向声明就好。

(3)声明成员函数的形参或者是返回类型,也可以利用前向声明的性质。

class String;
class Foo;
class Sample
{
public:
	Foo foo_test(Foo&);
private:
	String& s;
	Foo* f;
};

这里,我根本没有定义一个foo类,但是还是可以这样用,因为成员函数不占类对象的大小,所以c++编译器还是可以确定对象的大小(注:换句话说是否只要C++编译器能确定对象大小即可)。
前向声明的作用在于告诉编译器这是一个在别的地方定义的类型。这样C++编译器就能生成正确的符号表了。

(4) 即使前向声明一个没有定义的类,devc++也可以编译通过,如下所示:

#include <iostream>   
using namespace std;

class B;
class foo;

B func();

class A
{
public:
    B* t;
public:
    foo foo_test(foo&);
};

class B
{
public:
    int a;
public:
    B() {}
    virtual int add()
    {
        return 0;
    }
    static int c;
};

int main()
{
    A a;
    return 0;
}

上面代码也可以编译运行,即使没有看到class foo的定义;

转自:http://blog.csdn.net/damotiansheng/article/details/50916394

另一个使用了前向声明的例子:

class1.h

#pragma once
namespace RESR {
	struct Stucture1;//前向声明技术
	class Class1 {
	public :
		Stucture1* Get_a();
		void Set_a(Stucture1* x);
	private :
		Stucture1* a;
	};
}

structure1.h

#pragma once
namespace RESR {
	struct Stucture1 {
		int member;
	};
}

class1.cpp

#include"class1.h"

namespace RESR {
	Stucture1* Class1::Get_a() {
		return this->a;
	}
	void Class1::Set_a(Stucture1* x) {
		this->a = x;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值