C ++ Using member functions from a similar virtual public class

Suppose I have a bunch of inherited classes:

diamond

... and they all serve the purpose of creating all kinds of polynomials. A class Xis mainly a variable tank, classes A, Betc. - each virtual public Xand every one of them creates a type of the ont polynomial, the class Ymakes calls. In addition to Aand B, you can add any other class.

Now everything works, but for the newly added β€œvirtual public” class, I need to reuse some member functions from other classes, here from Ainside the class B. I tried to make a simple example:

#include <iostream>
#include <cmath>
#include <functional>

// variable tank
class X
{
protected:
    // general variables
    double *m_c;
    int m_n;
    double m_w;
    // funcX related
    double m_r;
    int m_i {0};

public:
    ~X() = default;

    /* Simple bracketed root-finding. This is called from more than
     * one "virtual public" classes.
     */
    const double funcX(const double &x, const double &y,    \
                       std::function<const double(const double&, const int&)> fp,   \
                       const int &k)
    {
        double a {x}, b {y}, fmid;
        while (m_i<100)
        {
            m_r = 0.5*(a + b);
            fmid = fp(m_r, k);
            if (fabs(b-a) <= 1e-3)
                break;
            if (fmid < 0)
                b = m_r;
            else
                a = m_r;
            ++m_i;
        }
        return m_r;
    }
};

// one of the many classes that generate polynomials
class A: virtual public X
{
public:

    void funcA(const int &n)
    {
        // set order
        m_n = n;
        // calculate X::m_c[i]
        m_c = new double[m_n+1];
        for (short i=0; i<=m_n>>1; ++i)
        {
            int sgn {i%2 ? -1 : 1};
            m_c[i<<1] = sgn/((i + 1.0)*(i + 1.0));
        }
        // The polynomial is zero somewhere, use funcX() to find where.
        m_w = funcX(5.0, 0.0,   \
                    [this](const double &x, const int &n)   \
                    { return calcA(x, n); },    \
                    m_n);
    }

    // calculates the value of the polynomial of order n, at x
    const double calcA(const double &x, const int &n) const
    {
        double out {static_cast<double>(m_c[0])};
        for (short i=1; i<=n; ++i)
            out = m_c[i] + x*out;
        return out;
    }
};

class B: virtual public X
{
private:
    A m_a;  // otherwise the lambda function does not "catch" it
public:
    void funcB(const int &n)
    {
        // same as in A
        m_n = n;
        // same as in A, calculate coefficients
        m_c = new double[m_n+1];
        for (short i=0; i<=m_n; ++i)
        {
            int sgn {i%2 ? -1 : 1};
            m_c[i] = sgn/((i + 1)<<1);
        }
        /* Here I need A::calcA(). Instead of duplicating the code,
         * I want to call it through X::funcX(). The code compiles,
         * but it crashes.
         */
        m_w = funcX(0.5, 1.0,   \
                    [this](const double &x, const int &n)   \
                    { return m_a.calcA(x, n); },    \
                    m_n);
    }
    const double getW() const { return m_w; }
};

class Y: public A, public B
{
public:
    Y(const int &n, const int &i)
    {
        // call one of the "virtual public" classes through i
        switch (i)
        {
        case 1: funcA(n);    break;
        case 2: funcB(n);    break;
        }
    }
    void printC() { for (short i=0; i<=m_n; ++i) std::cout << m_c[i] << '\n'; }
    void printW() { std::cout << m_w << '\n'; }
    void printA(const double &x, const double &n) { std::cout << A::calcA(x, n) << '\n'; }
};

int main(int argc, char *argv[])
{
    int N {6};
    Y *y;
    for (short i=1; i<=2; ++i)
    {
        y = new Y(N, i);
        y->printC();
        y->printW();
        y->printA(1.2, N);
    }

    return 0;
}

class X:

X::funcX() - , virtual public (A, B ..). m_c, m_n, m_w .

classes A B:

funcA() ( funcB() ..) ( , for), , X::m_n. A::calcA(). class B, . - . "" ...

class Y

virtual public i (switch/case).

, . . A::funcA() , , m_c[i] , m_c[0] . new double[] insode A, .

, . , ? , ?


: , calcA() A , X, -, , , . X::calcA() , , .

+4
1

, . , :

  • " ". . , . .
  • . , . , , .
  • . , , .

. , . , , . , , . , -, . , . . , . Y . , . , funcA funcB func, .

+4

Source: https://habr.com/ru/post/1656512/


All Articles