三个类之间的相互调用实现

简介: 在项目开发的时候,定义了三个核心类(ClassA,ClassB, ClassC),三个类之间存在调用关系如下:ClassC是管理类,需要调用ClassA, ClassB的接口;同时作为被管理类,ClassA, ClassB需要又需要调用ClassC的接口。

由来

在项目开发的时候,定义了三个核心类(ClassA,ClassB, ClassC),三个类之间存在调用关系如下:ClassC是管理类,需要调用ClassA, ClassB的接口;同时作为被管理类,ClassA, ClassB需要又需要调用ClassC的接口。

理清楚三类之间的关系:

1)定义顺序:ClassA, ClassB先于ClassC。

2)调用关系:ClassC要调用ClassA的接口、ClassB的接口;ClassA要调用ClassC的接口,classB要调用ClassC的接口。

其实,理清楚1),2)后我们发现,ClassA与ClassB之间并无直接调用关系(如果可以复杂点的话,可以再加处理)。

核心点:两个类需要相互调用对端类的接口时,需要主要包含对方头文件及前向声明的问题,这个网上都有不少网友解答。举例上面ClassA与ClassC的关系如下:

第一步:定义ClassA.h , classA.cpp , ClassC.h ClassC.cpp;

第二步:在ClassC.h头文件加上 #include “ClassA.h”, 在ClassC的cpp文件中加上#include “ClassC.h”;

第三步:在ClassA.h头文件中加上 #include “ClassA.h”, 在ClassA的cpp文件中加上 #include “ClassA.h” , #include “ClassC.h”。

上面的不清楚的话,详见实践代码:

代码实现:

/*
**ClassA.h
*/
#ifndefCLASSA_H_H
#defineCLASSA_H_H
 
classClassC;
 
classClassA
{
public:
       ClassA(ClassC* pC);
       ClassA();
       ~ClassA();
 
public:
       void displayA();
       void invoke_classC_in_ClassA();
 
public:
       ClassC* m_pC;
};
 
#endif
 
/*
**ClassA.cpp
*/
#include"stdafx.h"
#include"ClassA.h"
#include"classC.h"
#include<iostream>
usingnamespace std;
 
ClassA::ClassA(ClassC*pC)
{
       cout << "ClassA(ClassC* pC)constructor is running!" << endl;
       m_pC = pC;
}
 
ClassA::ClassA()
{
       cout << "ClassA() constructoris running!" << endl;
      
}
ClassA::~ClassA()
{
       cout << "ClassA destructor isrunning!" << endl;
}
 
 
voidClassA::invoke_classC_in_ClassA()
{
       cout <<"ClassA::invoke_classC_in_ClassA() is running" << endl;
       m_pC->displayC();
}
 
voidClassA::displayA()
{
       cout << "classA::displayA() isrunning!" << endl;
}
 
/*
**ClassB.h
*/
#ifndefCLASSB_H_H
#defineCLASSB_H_H
 
classClassC;
 
classClassB
{
public:
       ClassB(ClassC* pC);
       ClassB();
       ~ClassB();
 
public:
       void displayB();
       void invoke_classC_in_ClassB();
 
public:
       ClassC* m_pC;
 
};
 
#endif
 
/*
**ClassB.cpp
*/
 
#include"stdafx.h"
#include"ClassB.h"
#include"classC.h"
#include<iostream>
usingnamespace std;
 
ClassB::ClassB(ClassC*pC)
{
       cout << "ClassB(ClassC* pC)constructor is running!" << endl;
       m_pC = pC;
}
 
ClassB::ClassB()
{
       cout << "ClassB() constructoris running!" << endl;
      
}
ClassB::~ClassB()
{
       cout << "ClassB destructor isrunning!" << endl;
}
 
 
voidClassB::displayB()
{
       cout << "ClassB::displayB() isrunning!" << endl;
}
 
voidClassB::invoke_classC_in_ClassB()
{
       cout <<"ClassB::invoke_classC_in_ClassB() is running!" << endl;
 
       m_pC->displayC();
}
 
/*
**ClassC.h
*/
#ifndefCLASSC_H_H
#defineCLASSC_H_H
 
#include"ClassA.h"
#include"ClassB.h"
 
 
classClassC
{
public:
       ClassC();
       ~ClassC();
 
public:
       void displayC();
       void invoke_ClassA_in_ClassC();
       void invoke_ClassB_in_ClassC();
 
public:
       ClassA* m_pA;
       ClassB* m_pB;
};
 
#endif
 
/*
**ClassC.cpp
*/
#include"stdafx.h"
#include"ClassC.h"
#include<iostream>
usingnamespace std;
 
ClassC::ClassC()
{
       cout << "ClassC() constructoris running!" << endl;
 
       m_pA = new ClassA();
       m_pB = new ClassB();
      
}
ClassC::~ClassC()
{
       cout << "ClassC destructor isrunning!" << endl;
       if(NULL != m_pA)
       {
              delete m_pA;
              m_pA = NULL;
       }
       if(NULL != m_pB)
       {
              delete m_pB;
              m_pB = NULL;
       }
}
 
 
voidClassC::displayC()
{
       cout << "ClassC::displayC() isrunning!" << endl;
}
 
voidClassC::invoke_ClassA_in_ClassC()
{
       cout <<"ClassC::invoke_ClassA_in_ClassC() is running!" << endl;
       m_pA->displayA();
}
 
voidClassC::invoke_ClassB_in_ClassC()
{
       cout <<"ClassC::invoke_ClassB_in_ClassC() is running!" << endl;
       m_pB->displayB();
}
 
/*
**main.cpp
*/
#include"stdafx.h"
#include"ClassA.h"
#include"ClassB.h"
#include"ClassC.h"
#include<iostream>
using namespacestd;
 
intmain(int argc, char* argv[])
{
       ClassC* pC = new ClassC;
 
       cout << "C类调用A类:" << endl;
       pC->invoke_ClassA_in_ClassC();
 
       cout << endl << "C类调用B类:" << endl;
       pC->invoke_ClassB_in_ClassC();
 
 
       cout << endl << "A类调用C类:" << endl;
       ClassA* pA = new ClassA(pC);
       pA->invoke_classC_in_ClassA();
 
       cout << endl << "B类调用C类:" << endl;
       ClassB* pB = new ClassB(pC);
       pB->invoke_classC_in_ClassB();
 
       cout << endl;
    delete pB;
       delete pA;
       delete pC;
 
       return 0;
}

运行结果:

image.png
 

       
反思
其实完全可以转嫁为两个类之间的关系,类多了以后,理清类的单一职责原则,以及类之间的关系,类之间的调用接口很重要!


作者:铭毅天下
来源:CSDN
原文:https://blog.csdn.net/laoyang360/article/details/9866953
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章
|
存储 数据库 文件存储
掌握Django文件处理:一步步构建上传功能
文件上传算是一种很常见的需求,几乎构建很多项目系统,以及插件都需要用到。 通过上面例子可以看到django通过forms表单的形式灵活定义文件上传的页面,字段,以及数据库存储。 在实际项目中我们还要考虑到安全性,包括检查文件大小(可通过FileField的max_length属性设置)、防止路径遍历攻击。 还需注意服务器端的验证,比如检查文件类型、内容安全等。
|
Web App开发 数据采集 JavaScript
CDP与Selenium相结合——玩转网页端自动化数据采集/爬取程序
本文介绍了Selenium、Chrome DevTools及Chrome DevTools Protocol (CDP) 的基本功能与应用。Selenium是一款开源自动化测试工具,适用于网页端应用程序测试和数据采集,具备跨平台特性。Chrome DevTools内置浏览器中,提供调试、分析Web应用程序的功能,包括元素、控制台、源代码和网络选项卡等。CDP是一套用于与Chromium内核浏览器通信的API,支持自动化测试和性能分析。文中还展示了Selenium与CDP结合使用的示例,如捕获网络请求数据和打印网页内容,并推荐了相关书籍和资源以供深入学习。
1556 39
CDP与Selenium相结合——玩转网页端自动化数据采集/爬取程序
|
2天前
|
云安全 人工智能
2025,阿里云安全的“年度报告”
拥抱AI时代,阿里云安全为你护航~
1439 1
|
9天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1415 10
|
9天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1330 7
|
10天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
1215 15
|
4天前
|
人工智能 前端开发 API
Google发布50页AI Agent白皮书,老金帮你提炼10个核心要点
老金分享Google最新AI Agent指南:让AI从“动嘴”到“动手”。Agent=大脑(模型)+手(工具)+协调系统,可自主完成任务。通过ReAct模式、多Agent协作与RAG等技术,实现真正自动化。入门推荐LangChain,文末附开源知识库链接。
455 118
|
2天前
|
机器学习/深度学习 测试技术 数据中心
九坤量化开源IQuest-Coder-V1,代码大模型进入“流式”训练时代
2026年首日,九坤创始团队成立的至知创新研究院开源IQuest-Coder-V1系列代码大模型,涵盖7B至40B参数,支持128K上下文与GQA架构,提供Base、Instruct、Thinking及Loop版本。采用创新Code-Flow训练范式,模拟代码演化全过程,提升复杂任务推理能力,在SWE-Bench、LiveCodeBench等基准领先。全阶段checkpoint开放,支持本地部署与微调,助力研究与应用落地。
334 1

热门文章

最新文章