我们知道C++的类应当是先定义,然后使用。但在处理相对复杂的问题、考虑类的组合时,很可能遇到俩个类相互引用的情况,这种情况称为循环依赖。

例如:

class A
{
public:
void f(B b);//以B类对象b为形参的成员函数
//这里编译错位,因为'B'为为止符号
}; class B
{
public:
void g(A a);
};

这里类A的公有成员函数f的形参是类B的对象,同时类B的公有成员函数g也以类A的对象为形参。由于在使用一个类之前,必须首先定义该类,因此无论将哪一个类的定义放在前面,都会引起编译错误。结局这个问题的方法,就是使用前向引用声明。前向引用声明,是在引用未定义的类之前,将该类的名字告诉编译器,试编译器知道那是一个类名。这样,当程序中使用这个类名时,编译器就不会认为是错误,而类的完整定义可以在程序的其他地方。在上述程序加上下面的前向引用声明,问题就解决了。

class B; //前向引用声明
class A//A类的定义
{
public://外部接口
void f(B b);//以B类对象b为形参的成员函数 }; class B//B类的定义
{
public://外部接口
void g(A a);//以A类对象a为形参的成员函数
};
 
 
使用前向引用声明虽然可以解决一些问题,但它并不是万能的。需要注意的是,尽管使用了前向引用声明,但是在提供一个完整的类声明之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。请看下面的程序段:
class Fred;    //前向引用声明
class Barney
{
Fred x; //错误:类Fred的声明尚不完善
};
class Fred
{
Barney y;
};

编译出错的原因是对此类Fred的前向引用声明只能说明Fred是一个类名,而不能给出该类的完整定义,因此在类Barney中不能定义类Fred的数据成员。

再看下面这一段程序:

class Fred;    //前向引用声明

class Barney
{
public:
void method()
{
x->yabbaDabbaDo(); //错误:Fred类的对象在定义之前被使用
}
private:
Fred* x; //正确,经过前向引用声明,可以声明Fred类的对象指针
}; class Fred
{
public:
void yabbaDabbaDo();
private:
Barney* y;
};

出错原因:类Barney的内联函数中使用了由x所指向、Fred类的对象,而此时Fred类尚未完整地定义。

应该记住:当你使用前向引用声明时,你只能使用被声明的符号,而不能涉及类的任何细节。

 
C++的类可以进行前向声明。但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类,只能用于定义指针、引用、以及用于函数形参的指针和引用。
而不能定义对象(因为此时编译器只知道这是个类,还不知道这个类的大小有多大),也不能访问类的对象,任何形式的访问都不允许(因为此时根本不知道有些什么成员)。等到类正式定义以后,就可以以各种方式使用该类了。

C++ 类的前向声明的用法的更多相关文章

  1. C++面向对象 - 类的前向声明的用法

    C++中的类应当是先定义,然后使用.但在处理相对复杂的问题,比如考虑类的组合时,有可能遇到两个类相互引用的情况,这种情况称为循环依赖. 考虑下面代码: class A { public: void f ...

  2. C++12.1.4 类的前向声明、不完全类型类

    只声明却没有定义的类称为—————–不完全类型,不完全类型不能定义该类型的对象,只能用于定义指向该类型的指针及引用,或者用于声明(不是定义)使用该类型作为形参类型或返回类型的函数. 在创建类的对象之前 ...

  3. C++中类的前向声明的用法

    原创文章,未经博主允许禁止转载. C++的类可以进行前向声明.但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类,只能用于定义指针.引用.以及用于函数形参的指针和引用.而不能定义对象(因为此时编 ...

  4. C++ 类的前向声明

    前向声明 在计算机程序设计中, 前向声明是指声明标识符(表示编程的实体,如数据类型.变量.函数)时还没有给出完整的定义.即可以声明一个类而不定义它,只声明类但不知道类的成员变量.函数等具体细节. 如: ...

  5. C++中类的前向声明

    概念 可以声明一个类而不是定义它; class Screen; 这个声明被称为"前向声明".在声明之后,定义之前,类screen是一个不完全类型,即已知Screen是一个类型,但不 ...

  6. c++中的前向声明

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

  7. 类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等

    一.类声明 //类是一种用户自定义类型,声明形式: class 类名称 {    public:              公有成员(外部接口)    private:              私有 ...

  8. 转 : c++ 结构体 前向声明

    typedef struct tag_guid { ULONGLONG utime; ULONGLONG umac; }tpguid; class A { private: int m_teset1; ...

  9. 12.1——类的定义与声明,隐含的this指针

    类的定义与声明: (1)将const放在成员函数的形参列表之后,可以将将成员函数声明为常量,而它的意思是函数不能改变所操作的数据成员 这里必须在声明和定义处都加上const. (2)成员函数有一个隐含 ...

随机推荐

  1. SpringBoot启动过程源码分析

    学习博客:SpringBoot时序图分析启动过程

  2. Network出现两次相同请求?

    出现的状况 Network中出现了两个相同的请求(如图),两个发起了同样的请求,花的时间却不同,一个55ms,一个花了294ms.   两个相同的请求 什么情况啊?研究了一番,我发现有一个地方是不同的 ...

  3. 01-linux介绍

    一.Linux简介 Linux内核最初只是由芬兰人林纳斯.托瓦兹在大学时出于爱好写出来的,是一套免费使用和自由传播的类Unix操作系统,是基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU ...

  4. Spring Boot 2 快速教程:WebFlux Restful CRUD 实践(三)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第102篇原创 03:WebFlux Web CR ...

  5. opencv-python 图像处理(五)

    Canny边缘检测 1) 使用高斯滤波器,以平滑图像,滤除噪声. 2) 计算图像中每个像素点的梯度强度和方向. 3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测 ...

  6. 【JDBC】CRUD操作

    JDBC的CRUD操作 向数据库中保存记录 修改数据库中的记录 删除数据库中的记录 查询数据库中的记录 保存代码的实现 package demo1; import java.sql.Connectio ...

  7. Jenkins自动化部署入门详细教程

    大纲 1.背景 在实际开发中,我们经常要一边开发一边测试,当然这里说的测试并不是程序员对自己代码的单元测试,而是同组程序员将代码提交后,由测试人员测试: 或者前后端分离后,经常会修改接口,然后重新部署 ...

  8. NFS共享储存

    目录 NFS 为什么要使用共享存储 集群没有共享存储的情况 集群有共享存储 NFS的工作原理 NFS部署 1.环境准备 2.关闭防火墙和selinux 3.部署nfs服务端 4.启动rpcbind 5 ...

  9. Python list遍历remove()时的一个小BUG

    有这样一个列表: s=list('abcdefg') 现在因为某种原因我们需要从s中踢出一些不需要的元素,方便起见这里直接以踢出所有元素的循环代替: for e in s: s.remove(e) 结 ...

  10. Sublime Text 3如何关闭自动更新

    1.Preferences -> Settings-User 2.插入下面代码:"update_check": false 如果有其他的设置,用逗号隔开,然后保存 3.Pre ...