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

https://www.cnblogs.com/zhaojk2010/p/5789354.html

原文地址:https://www.cnblogs.com/wkfvawl/p/10801725.html

时间: 2024-10-13 08:27:33

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

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

原创文章,未经博主允许禁止转载. C++的类可以进行前向声明.但是,仅仅进行前向声明而没有定义的类是不完整的,这样的类,只能用于定义指针.引用.以及用于函数形参的指针和引用.而不能定义对象(因为此时编译器只知道这是个类,还不知道这个类的大小有多大),也不能访问类的对象,仍和形式的访问都允许(因为此时根本不知道有些什么成员).等到类正式定义以后,就可以以各种方式使用该类了. //前向声明此类 class Video; //此时,只能定义指针和引用.不能定义对象,也不能以任何方式调用对象的成员 vo

C++类的前向声明

前向声明的定义:有些时候我们可以声明一些类但是并不去定义它,当然这个类的作用也很有限了. 比如class foo; 声明一个foo类,这个声明,有时候也叫做前向声明(forward declaration),在声明完这个foo类之后,定义完这个foo类之前的时期,foo类是一个不完全的类型(incomplete type),也就是说foo类是一个类型,但是这个类型的一些性质(比如包含哪些成员,具有哪些操作)都不知道. 因此这个类的作用也很有限. (1)不能定义foo类的对象. (2)可以用于定义

类的前向声明

前向声明的定义:有些时候我们可以声明一些类但是并不去定义它,当然这个类的作用也很有限了. 比如class foo; 声明一个foo类,这个声明,有时候也叫做前向声明(forward declaration),在声明完这个foo类之后,定义完这个foo类之前的时期,foo类是一个不完全的类型(incomplete type),也就是说foo类是一个类型,但是这个类型的一些性质(比如包含哪些成员,具有哪些操作)都不知道. 因此这个类的作用也很有限. (1)不能定义foo类的对象. (2)可以用于定义

c/c++基础(二十) 类的前向声明和#include区别

在头文件中引入另一个类经常有两种写法: (1)class Name; (2)#include "Name.h" 它们的区别是什么呢? 第一种叫做前向声明,在程序中引入了类类型为Name.在声明之后,定义之前,类Name是一个不完全类型(incompete type),即已知Name是一个类型,但不知道包含哪些成员.不完全类型只能以有限方式使用,不能定义该类型的对象,不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数.(前向声明

两个类相互包含引用的问题--类前向声明

1.背景 编程中遇到如下错误:使用不完全类型**以及**前向声明. 查找相关资料后发现是类的前向声明(forward declaration)问题:在程序中声明一个类后,此类是一个不完全类型(incompete type),即已知此类是一个类型,但不知道包含哪些成员. 不完全类型只能以有限方式使用,不能定义该类型的对象.不完全类型只能用于定义指向该类型的指针及引用,或者用于声明(而不是定义)使用该类型作为形参类型或返回类型的函数. 2.为什么需要前向声明 在构造自己的类时,有可能会碰到两个类之间

关于声明、定义、前向声明、include、循环依赖、普通友元函数、友元类、友元成员函数的总结

做<C++ Primer>(第5版)253页练习题7.3.4有感,故总结之 1 声明 1.1 变量和函数的声明 常见的声明是声明一个变量或函数,一般在头文件.h中声明,例如: pos cursor = 0; // 给定初始值 char get(pos r, pos col) const; 1.2 类的声明 对于一个类,一般是直接在头文件中直接写 class ClassName { ... },这称之为类的定义,然后在类体{...}中又声明或定义了成员变量和成员函数.类的声明是没有类体,只有个类

前向声明

前向声明的定义:有些时候我们可以声明一些类但是并不去定义它,当然这个类的作用也很有限了. 如:class A; 声明一个foo类,这个声明,有时候也叫做前向声明(forward declaration),在声明完这个foo类之后,定义完这个foo类之前的时期,foo类是一个不完全的类型(incomplete type), 也就是说foo类是一个类型,但是这个类型的一些性质(比如包含哪些成员,具有哪些操作)都不知道. 因此这个类的作用也很有限. (1)不能定义foo类的对象.(不能) (2)可以用

C++ Primer 学习笔记_15_类与数据抽象(1)_类的定义和声明

C++ Primer 学习笔记_15_类与数据抽象(1)_类的定义和声明 在C++中,用类来定义自己的抽象数据类型.通过定义类型来对应所要解决的问题中的各种概念,可以使我们更容易编写.调试和修改程序.可以使得自己定义的数据类型用起来与内置类型一样容易和直观. 看一下Sales_item类: class Sales_item { private: std::string isbn; unsigned units_sold; double revenue; public: double ave_pr

C++ Primer 学习笔记_48_类与数据抽象 --类的定义和声明【下】

类 --类的定义和声明[下] 三.关于类定义的更多内容[接上] //P374 习题12.8 class Sales_item { public: double avg_price() const; bool same_isbn(const Sales_item &rhs) const { return rhs.isbn == isbn; } Sales_item():units_sold(0),revenue(0){} private: std::string isbn; unsigned un