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

简介: 由来:在项目开发的时候,定义了三个核心类(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

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

相关文章
|
11月前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
515 60
|
Ubuntu Linux
在Linux中,如何查看当前系统的版本信息?
在Linux中,如何查看当前系统的版本信息?
|
数据采集 数据可视化 数据挖掘
学习笔记pirate
- 使用Python的`sklearn`进行数据预处理,包括AdaBoost回归器的网格搜索调优,处理时间序列数据,并执行数据可视化。 - 应用`transformers`库对预训练的语言模型进行微调,针对RTE、MRPC和SST-2任务进行文本分类,使用PEFT(Pointer Enhanced Fine-Tuning)模型。 - 进行图像分割任务,包括图像预处理、定义数据集、训练DeepLabV3 ResNet50模型。
|
存储 Linux 调度
太好用了!Python 定时任务调度框架 APScheduler 详解!
太好用了!Python 定时任务调度框架 APScheduler 详解!
1451 0
|
SQL 存储 数据可视化
基于PostgreSQL的索引推荐原理及最佳实践
基于PostgreSQL讲述索引推荐的原理、实现及最佳实践。
2238 0
基于PostgreSQL的索引推荐原理及最佳实践
|
数据可视化 数据挖掘 数据处理
数据科学手把手:碳中和下的二氧化碳排放分析 ⛵
气候是全球性的话题,本文基于owid co2数据集,分析了世界各地的二氧化碳排放量,并将二氧化碳排放的主要国家以及二氧化碳排放来源进行了可视化。
2484 1
数据科学手把手:碳中和下的二氧化碳排放分析 ⛵
|
Java Kotlin
Kotlin 范型之泛型约束、类型投影、星号投影
Kotlin 范型之泛型约束、类型投影、星号投影
507 0
|
开发工具 Android开发 UED
Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决
Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决 附录1的Android Ripple Effect水波波纹荡漾的视觉交互设计,在Android SDK版本21上运作良好,但是放到21版本以下,比如Android 4.
876 0