Возможно, вам не удастся создать виртуальные функции друзей, но вы можете создавать виртуальных операторов (даже operator +
может быть сделано таким образом).
Рассмотрите следующий код: ПРЕДУПРЕЖДЕНИЕ: ЭТО НЕ ХОРОШИЙ ДИЗАЙН ВСЕХ
#include <iostream>
using namespace std;
class AA {
private:
int a;
public:
AA(int a): a(a) {};
inline int getA() const { return a; };
virtual AA operator +(const AA &a) {
AA res(this->getA() + a.getA());
return res;
}
};
class BB: public AA {
public:
BB(int a): AA(a) {}
virtual AA operator +(const AA &a) {
AA res(this->getA() - a.getA());
return res;
}
};
int main() {
BB tmp(1);
AA& a = tmp;
AA b(7);
cout << (a + b).getA();
return 0;
}
Когда я писал этот код, я обнаружил, что может быть вызвано множество недостатков (например, оператор +, который вместо этого действительно вычитаетКроме того, что, если вторым операндом был BB вместо первого ??)
Итак, по поводу вашей проблемы, вам нужны скаляры.Таким образом, вы можете сделать следующий подход:
#include <iostream>
using namespace std;
// Here, Scalar acts as an abstract class, all its goal is to convert your
// class type into some calculable value type (e.g. you can use T as double)
template <typename T>
class Scalar {
public:
// Converter function is abstract
virtual operator T() = 0;
};
class AA: public Scalar<double> {
private:
double a;
public:
inline double getA() {return a;};
AA(double a): a(a) {}
// Implements the converter function in Scalar, T in scalar is mapped
// to double because we did Scalar<double>
virtual operator double() {
return a;
}
};
class BB: public Scalar<double> {
private:
int a;
public:
inline double getA() {return (double)a;};
BB(int a): a(a) {}
virtual operator double() {
return (double)a;
}
};
int main() {
BB tmp(1);
AA b(7);
// Here, it is easy for us just to add those, they are automatically converted into doubles, each one like how it is programmed.
cout << (b + tmp);
return 0;
}