C++面向对象 - 类的前向声明的用法
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 C1; //前向引用声明
class C2
{
C1 x; //错误:类C1的声明尚不完善
};
class C2
{
C1 y;
};
编译出错的原因是对此类C1的前向引用声明只能说明C1是一个类名,而不能给出该类的完整定义,因此在类C2中不能定义类型为类C1的数据成员。
class C1; //前向引用声明
class C2
{
public:
void method()
{
x->ceshi(); //错误:C1类的对象在定义之前被使用
}
private:
C1* x; //正确,经过前向引用声明,可以声明C1类的对象指针
};
class C1
{
public:
void ceshi();
private:
C2* y;
};
出错原因:类C2的内联函数中使用了由x所指向的C1类的对象,而此时C1类尚未完整地定义。
当你使用前向引用声明时,你只能使用被声明的符号,而不能涉及类的任何细节。
C++的类可以进行前向声明。但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类,只能用于定义指针、引用、以及用于函数形参的指针和引用。而不能定义对象(因为此时编译器只知道这是个类,还不知道这个类的大小有多大),也不能访问类的对象,任何形式的访问都不允许(因为此时根本不知道有些什么成员)。等到类正式定义以后,就可以以各种方式使用该类了。
C++面向对象 - 类的前向声明的用法的更多相关文章
- C++ 类的前向声明的用法
我们知道C++的类应当是先定义,然后使用.但在处理相对复杂的问题.考虑类的组合时,很可能遇到俩个类相互引用的情况,这种情况称为循环依赖. 例如: class A { public: void f(B ...
- C++12.1.4 类的前向声明、不完全类型类
只声明却没有定义的类称为—————–不完全类型,不完全类型不能定义该类型的对象,只能用于定义指向该类型的指针及引用,或者用于声明(不是定义)使用该类型作为形参类型或返回类型的函数. 在创建类的对象之前 ...
- C++ 类的前向声明
前向声明 在计算机程序设计中, 前向声明是指声明标识符(表示编程的实体,如数据类型.变量.函数)时还没有给出完整的定义.即可以声明一个类而不定义它,只声明类但不知道类的成员变量.函数等具体细节. 如: ...
- C++中类的前向声明的用法
原创文章,未经博主允许禁止转载. C++的类可以进行前向声明.但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类,只能用于定义指针.引用.以及用于函数形参的指针和引用.而不能定义对象(因为此时编 ...
- C++中类的前向声明
概念 可以声明一个类而不是定义它; class Screen; 这个声明被称为"前向声明".在声明之后,定义之前,类screen是一个不完全类型,即已知Screen是一个类型,但不 ...
- c++中的前向声明
整理于: http://blog.csdn.net/heyutao007/article/details/6649741 http://blog.sina.com.cn/s/blog_68d90fdb ...
- 类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等
一.类声明 //类是一种用户自定义类型,声明形式: class 类名称 { public: 公有成员(外部接口) private: 私有 ...
- 转 : c++ 结构体 前向声明
typedef struct tag_guid { ULONGLONG utime; ULONGLONG umac; }tpguid; class A { private: int m_teset1; ...
- 12.1——类的定义与声明,隐含的this指针
类的定义与声明: (1)将const放在成员函数的形参列表之后,可以将将成员函数声明为常量,而它的意思是函数不能改变所操作的数据成员 这里必须在声明和定义处都加上const. (2)成员函数有一个隐含 ...
随机推荐
- 【C# .Net GC】延迟模式 latencyMode 通过API-GC调优
延迟模式 lowlatency 使用环境:后台工作方式只影响第 2 代中的垃圾回收:第 0 代和第 1 代中的垃圾回收始终是非并发的,因为它们完成的速度很快.GC模式是针对进程配置的,进程运行期间不能 ...
- C#依赖注入-初步概念了解
维基百科说:"依赖注入是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分.该模式分离了客户端 ...
- JAVA只要掌握内部类,多继承和单继承都不是问题
摘要:如果实现java的多继承,其实很简单,关键是对于内部类的特征的掌握,内部类可以继承一个与外部类无关的类,保证了内部类天然独立性,根据这个特性从而实现一个类可以继承多个类的效果. 本文分享自华为云 ...
- vue+element ui后台遇到的坑
今天在用elementui做后台系统,遇到第一个坑:分页显示的是英文 按照官网组件复制下来的代码: <el-row :gutter="0" style="margi ...
- Oracle数据库sql命令整理
转至:https://blog.csdn.net/weixin_43712330/article/details/88358604 以下为oracle数据库中sql语句的整理,将持续更新01. 如何登 ...
- Hystrix&Dashboard配置使用
目录 Hystrix是什么 熔断 什么是熔断 熔断类型 打开 半开 关闭 使用方法 导包 添加启动注解 新增方法 测试 降级 什么是降级 使用方法 导包 修改yml,新增如下 启动类新增注解 @Ena ...
- laravel7 搜索分页
html: <form action="{{url('http://www.yanbing.com/fang/index')}}" method="get" ...
- AQS 源码解读之加锁篇
以 ReentrantLock 创建的非公平锁为基础,进行 AQS 全流程的分析. 分析 demo 一共有 A.B.C 三个线程. public class AQSDemo { // 带入一个银行办理 ...
- 原生 JS 实现 VS Code 自动切换输入法状态!这次没有AHK
上一篇文章:使用 AHK 在 VS Code 中根据上下文自动切换输入法状态 给出一个使用 ahk 在 VSCode 自动切换输入法的方法.不过这个方法实际上很蹩脚,一点都不优(zhuang)雅(bi ...
- How to Rebase Git Branch
转自:How to Rebase Git Branch (with 3 steps) | Git Rebase | W3Docs Steps to rebasing branch Fetching c ...