现在的位置: 首页 > 综合 > 正文

类的向前声明

2017年12月15日 ⁄ 综合 ⁄ 共 911字 ⁄ 字号 评论关闭
文章目录

1 在类 B 的头文件中声明 类 A 的指针 pA

//  A.h 头文件
#pragma once
class A
{
public:
	void Action();
};
// B.h 头文件
#pragma once
<strong>class A;</strong>
class B
{
public:
	B(A*);
private:
	A *pA; // Ok
};

在类 B 的声明头文件中必须前置声明类 A,否则,编译器报:语法错误,标识符 A。

2  在类 B 的头文件中引用类 A 的指针 pA,且在类 B 的第二格构造函数中调用 A::Action 函数

//  A.h 头文件
#pragma once
class A
{
public:
	void Action();
};
// B.h 头文件
#pragma once
class A;
class B
{
public:
	B(A *pa)
	{
		pa->Action(); // error
	}
private:
	A *pA; // Ok
};

编译器报错,不知道 A 的定义。

3 在类 B 的头文件中声明类 A 的变量 a

//  A.h 头文件
#pragma once
class A
{
public:
	void Action();
};
// B.h 头文件
#pragma once
class A;
class B
{
public:
	B(A*);
private:
	A *pA; // Ok
	//A a; // error, 不知道 A 的类型信息,无法求得 B 对象中 a 的具体大小值
};

编译器报错,不知道 A 的定义。

4 在类 B 的头文件中声明类 A 的引用

//  A.h 头文件
#pragma once
class A
{
public:
	void Action();
};
// B.h 头文件
#pragma once
class A;
class B
{
public:
	B(A& ref) : refA(ref) 
        {
        }
private:
	A &refA; // Ok
};

why?

2、3的错误原因是一样的。因为编译器不知道 A 的类型信息,所以不知道 A的具体长度,因此不能分配空间。在编译期,编译器必须知道 A 的大小,才能在构造 A 实例时分配具体大小的空间。注:并非只在创建实例时才必须知道B类型的大小,编译时,也必须知道。

1 、4正确的原因是一样的。因为声明的 A 的指针 pA 或者声明 A 的引用(引用是由指针来实现的),任何类型的指针或引用变量的大小都是确定的,所以编译器可以知道其大小。

【上篇】
【下篇】

抱歉!评论已关闭.