博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++不完整的类型
阅读量:4873 次
发布时间:2019-06-11

本文共 1841 字,大约阅读时间需要 6 分钟。

今天写C++primer 5th中文版第422页的程序时,出现了”不允许使用不完整的类型“的错误,下面我就用类A 与 类B 作为代表,重现一下该错误,并且提出解决方案。

一、带问题的类设计A:

1、类A放在A.h 与 A.cpp中

2、由于B需要访问A的私有成员,故声明B是其友元类

3、A中需要利用自身作为参数去创建一个新的B类实例。

代码如下:A.cpp中就是一个空的析构函数的实现。。。没什么,我把主要实现都写在了A.h中

1 #pragma once 2 #include
3 4 class B; // 声明B 从而能够在下文声明为友元类 5 class A 6 { 7 public: 8 friend class B; // 声明B为友元类 9 A(int a) :data(a){}10 11 B Pirnt() // 打印一行文字并且调用B的构造函数:B(A &a, int secParam = 5)创建一个B的实例12 {13 std::cout << "hehe " << std::endl;14 return B(*this);15 }16 ~A();17 private:18 int data;19 };

二、带问题的类设计B

1、B 接受一个A 引用参数,达成构造B的目的

同样的,B.cpp中也是一个空的构造函数与一个空的析构函数,下面展示的是B.h中的代码:

1 #pragma once 2 #include "A.h" 3 class B 4 { 5 public: 6     B(A &a, int secParam = 5) :data(a.data){} 7     B(); 8     ~B(); 9 10 private:11     int data;12 };

 

三、问题提示:

在A.h的第11 与 14行使用B的地方提示”B不是完整的数据类型“

四、分析

首先,我们需要在类A中将B声明为友元类,此时类B尚未定义,故仅在class A前面声明了class B;然后在此利用B进行代码编写,但是带来了问题:

这种声明叫做 前向声明,它在声明之后,定义之前的这段时间,它都是不完整的,对于类A中的代码来讲,他们不知道B什么时候定义,所以编译器直接认为B是不完整的。。。

如果分别在A.h与B.h中包含对方的头文件,又造成了循环包含。

五、解决方案。

1、将A  B写在一个头文件中

2、声明A,定义B

3、定义A

代码:

A.h

#pragma once#include
class A; // 声明Aclass B{public: B(A &a, int secParam = 5); // 只可声明,不能在此处定义,具体定义在B.cpp中写 ~B();private: int data;};class A{public: friend class B; // 声明B为友元类 A(int a) :data(a){} B Pirnt() // 打印一行文字并且调用B的构造函数:B(A &a, int secParam = 5)创建一个B的实例 { std::cout << "hehe " << std::endl; return B(*this); } ~A();private: int data;};

B.cpp

#include "A.h"B::B(A &a, int secParam) :data(a.data){}B::~B(){}

对于A.cpp,还是空的构造函数与析构函数

原因:

1、上文说道在类声明与定义之间的时间内,其是不完整的,不可使用的,但是  可以定义指向这种类型的指针和引用,可以声明(不能定义)以不完整类型作为参数或者返回类型的函数。

故,可以先在B中的构造函数里使用 A& 这个参数.

不过使用A&作为参数的那个构造函数的实现(定义)需要在cpp中写,因此执行到CPP的时候,A已经是完整的了。

2、 执行到A时,B的各成员声明已经完整。

转载于:https://www.cnblogs.com/tntboom/p/4404286.html

你可能感兴趣的文章
mysql 时间设置
查看>>
如何在 Xcode 中修改应用的名字
查看>>
[BZOJ5334][TJOI2018]数学计算(exgcd/线段树)
查看>>
[BZOJ4340][BJOI2015]隐身术(后缀数组)
查看>>
有关交换机——熟悉原理是必须的【转载】
查看>>
ACM(数学问题)——UVa202:输入整数a和b(0≤a≤3000,1≤b≤3000),输出a/b的循环小数表示以及循环节长度。...
查看>>
【转】Android 读取doc文件
查看>>
P2602 [ZJOI2010]数字计数 (数位dp or 思维)
查看>>
C# 访问 C DLL
查看>>
Matlab与方程组
查看>>
NYOJ 477
查看>>
华为、科达、海康、大华等厂家摄像头通过非标方式(RTSP)接入流媒体服务实现WEB直播与录像...
查看>>
OSPF笔记
查看>>
PHP之abstract
查看>>
Rappid 消除试用版的弹出框
查看>>
精华 ionic入门之色彩、图标、边距和界面组件:列表
查看>>
顺变者昌
查看>>
Linux上vi(vim)编辑器使用教程
查看>>
promise intro2-用法
查看>>
极客范:如何使用 Cloud Insight 来监控闭路电视?
查看>>