前向声明之“Error: pointer to incomplete class type is not allowed.”

在编译C++文件时有时候遇到这个问题,其实这是因为我们使用了前向声明(forward declaration)。

来自wiki的定义,在计算机程序设计中, 前向声明是指声明标识符(表示编程的实体,如数据类型、变量、函数)时还没有给出完整的定义。

例如:

ClassA.h

#pragma once

class ClassB;
class ClassA
{
public:
	ClassA(void);
	~ClassA(void);
public:
	void Fun(ClassB & classB);
public:
	ClassB * m_classB;
};

在ClassA中有ClassB * 类型的成员变量,而ClassB没有完全定义,我们这里只给出了class ClassB;的声明,类ClassB是一个不完全类型(Incompete type)。

在C++中,类型有Complete type和Incomplete type之分,对于Complete type, 它的大小在编译时是可以确定的,而对于Incomplete type, 它的大小在编译时是不能确定的。因此,不完全类型只能以有限方式使用,不能定义该类型的对象,不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数。

通常,假设声明两个类A和B,如果需要在A.h中定义B类对象,B b; 势必要包含#include "B.h";而B类中需要定义A类对象A a; 也要包含B.h。但是相互包含是不允许的,称为环形引用,这时候就用到了前向声明。

接着上面的例子,完整的代码如下:

ClassA.cpp

#include "ClassA.h"
#include "ClassB.h"//因为ClassA.h使用了ClassB的前向声明,这里需要包含ClassB.h才能获得ClassB的全部信息。

ClassA::ClassA(void)
{
}

ClassA::~ClassA(void)
{
}

void ClassA::Fun(ClassB & classB)
{
	m_classB = &classB;
	int v = m_classB->GetValue();
}
ClassB.h

#pragma once

#include "ClassA.h"

class ClassB
{
public:
	ClassB(void);
	~ClassB(void);
public:
	int GetValue() const { return m_Value; }
	void SetValue(int val) { m_Value = val; }
private:
	int m_Value;
};
ClassB.cpp

#include "ClassB.h"

ClassB::ClassB(void)
{
	m_Value = 123;
}

ClassB::~ClassB(void)
{
}
前向声明可以解决互相引用的困境,也可以在一定程度上提高编译速度,这是我们需要前向声明的主要原因。



  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值