简体   繁体   中英

How to call derived class function from pointer to base class type (C++)

Context: I'm developing a communications protocol for an embedded application.
The protocol basically needs to be a wrapper allowing it to be ported to different communications methods (Serial, WiFi, Bluetooth, etc) and be able to support communication with and control of different peripherals (DAC, accelerometer, etc).

The idea is that each communications method ( A_base in my example) would have its own implementation while having the same external functions, such that the code for the peripherals would not need to be rewritten if (for example) we moved from bytes-over-serial to json-over-wifi.
Each peripheral implements a derivative of a base class ( B_base in my example) to handle the transmission of data specific to that peripheral, hence each B must be able to call functions from derivatives of A_base without necessarily knowing which derivative has been used.

When I compile code which is written in the same way as the following, I get errors such as:

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&)'
then
baseClasses.h:xx:yy: note: candidate: virtual void A_base::callFromB()
virtual void callFromB() =0;
candidate expects 0 arguments, 2 provided

Have I implemented the functionality I described wrong, or is it simply not possible, or does it require a specific version of C++?
I'm not an experienced C++ programmer, so any help would be greatly appreciated.

Example code:

BASE CLASSES

/* ==== 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);
}

DERIVATIVE OF 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
}

DERIVATIVE OF 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]);
}

MAIN PROGRAM

#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;
}

You have a pure virtual function virtual void callFromB() =0; that is not being overridden in the derived class ie:

virtual void callFromB(const char*, int); != virtual void callFromB() 

You can change A_base::callFromB() to A_base::callFromB(const char*, int)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM