如何从指向基类类型的指针调用派生类函数(C++)
Posted
技术标签:
【中文标题】如何从指向基类类型的指针调用派生类函数(C++)【英文标题】:How to call derived class function from pointer to base class type (C++) 【发布时间】:2018-01-11 04:34:52 【问题描述】:上下文:我正在为嵌入式应用程序开发通信协议。 该协议基本上需要成为一个包装器,使其能够移植到不同的通信方法(串行、WiFi、蓝牙等),并能够支持与不同外围设备(DAC、加速度计等)的通信和控制。
这个想法是每个通信方法(在我的示例中为A_base
)将有自己的实现,同时具有相同的外部功能,这样如果(例如)我们移动了外围设备的代码就不需要重写从字节到串行到 json-over-wifi。
每个外设实现基类的派生(在我的示例中为B_base
)来处理特定于该外设的数据的传输,因此每个B
必须能够从A_base
的派生中调用函数,而不必知道哪个派生已使用。
当我编译以与以下相同的方式编写的代码时,会出现以下错误:
derivedB.cpp: In member function 'virtual void derivedB::setupData()':
derivedB.cpp:xx: error: no matching function for call to 'A_base::callFromB(const char*, int&)'
然后baseClasses.h:xx:yy: note: candidate: virtual void A_base::callFromB()
virtual void callFromB() =0;
candidate expects 0 arguments, 2 provided
我是否实现了我描述错误的功能,或者根本不可能,或它是否需要特定版本的 C++? 我不是一个有经验的 C++ 程序员,所以任何帮助将不胜感激。
示例代码: 基类
/* ==== baseClasses.h ==== */
#ifndef BASECLASSES_H
#define BASECLASSES_H
#include <list>
// forward declarations
class A_base;
class B_base;
class A_base
protected:
std::list<B_base*> listOfBs;
public:
A_base();
void addB(B_base*);
virtual void callFromB() =0;
virtual void alsoCallFromB(short*, int) =0;
virtual void alsoCallFromB(int*, int) =0;
virtual void alsoCallFromB(float*, int) =0; // overloaded
;
class B_base
protected:
int someCommonInt;
A_base* A;
public:
B_base(int, A_base&);
virtual void setupData() =0;
;
#endif
/* ==== baseClasses.cpp ==== */
#include "baseClasses.h"
A_base::A_base()
void A_base::addB(B_base* b listOfBs.push_back(b);
B_base::B_base(int i, A_base& ref_A)
someCommonInt = i;
A = &ref_A;
A->addB(this);
A 的导数
/* ==== A_derived.h ==== */
#include "baseClasses.h"
class derivedA : public A_base
public:
virtual void callFromB(const char*, int);
virtual void alsoCallFromB(short*, int);
virtual void alsoCallFromB(int*, int);
virtual void alsoCallFromB(float*, int); // overloaded
;
/* ==== A_derived.cpp ==== */
#include "A_derived.h"
void derivedA::callFromB(const char* msg, int foo)
// do something with msg and foo
void derivedA::alsoCallFromB(short* data, int len=1) // overloaded derived function with default value
// do something with short int data
void derivedA::alsoCallFromB(int* data, int len=1) // overloaded derived function with default value
// do something with int data
void derivedA::alsoCallFromB(float* data, int len=1) // overloaded derived function with default value
// do something with float data
B 的导数
/* ==== B_derived.h ==== */
#include "baseClasses.h"
class derivedB : public B_base
private:
int* intData;
float* floatData;
int arraySize;
public:
virtual void setupData(int*, float*, int);
void callAWithDataArrays();
void callAWithSingleValue(int);
;
/* ==== B_derived.cpp ==== */
#include "B_derived.h"
void derivedB::setupData(int* iPtr, float* fPtr, int size)
intData = iPtr;
floatData = fPtr;
arraySize = size;
A->callFromB("B setup done.\n", 0);
void derivedB::callAWithDataArrays()
A->alsoCallFromB(intData, arraySize);
A->alsoCallFromB(floatData, arraySize);
void derivedB::callAWithSingleValue(int idx)
A->alsoCallFromB(intData[idx]);
A->alsoCallFromB(floatData[idx]);
主程序
#include "A_derived.h"
#include "B_derived.h"
int main(int argc, char** argv)
int myInts[] = new int[8];
float myFloats[] = new float[8];
float anotherFloat = 1.23;
A_derived myA;
B_derived myB(1337, (A_base&)myA);
myB.setupData(myInts, myFloats, 8);
myB.callAWithDataArrays();
myB.callAWithSingleValue(4);
return 0;
【问题讨论】:
【参考方案1】:你有一个纯虚函数virtual void callFromB() =0;
,它没有在派生类中被覆盖,即:
virtual void callFromB(const char*, int); != virtual void callFromB()
你可以改A_base::callFromB() to A_base::callFromB(const char*, int)
【讨论】:
以上是关于如何从指向基类类型的指针调用派生类函数(C++)的主要内容,如果未能解决你的问题,请参考以下文章