C++ C++;使用类似虚拟公共类中的成员函数

C++ C++;使用类似虚拟公共类中的成员函数,c++,class,C++,Class,假设我有一堆继承的类,如下所示: …它们都是用来做各种多项式的。ClassX主要是一个变量箱,Classa,B等都是虚拟公共X,每个都创建一个类型的多项式,ClassY进行调用。除了A和B之外,还可以添加任何其他类 现在,一切正常,但对于新添加的“虚拟公共”类,我需要重用其他类中的一些成员函数,这里是从a类B内部。我试着举一个最简单的例子: #include <iostream> #include <cmath> #include <functional>

假设我有一堆继承的类,如下所示:

…它们都是用来做各种多项式的。Class
X
主要是一个变量箱,Class
a
B
等都是
虚拟公共X
,每个都创建一个类型的多项式,Class
Y
进行调用。除了
A
B
之外,还可以添加任何其他类

现在,一切正常,但对于新添加的“虚拟公共”类,我需要重用其他类中的一些成员函数,这里是从
a
B
内部。我试着举一个最简单的例子:

#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;
}
#包括
#包括
#包括
//可变油箱
X类
{
受保护的:
//一般变量
双*m_c;
国际货币基金组织;
双m_w;
//funcX相关
双m_r;
int m_i{0};
公众:
~X()=默认值;
/*简单的括号内的根查找。这是从多个
*一个是“虚拟公共”类。
*/
常数双函数(常数双函数&x,常数双函数&y\
std::函数fp\
康斯特(国际和韩国)
{
双a{x},b{y},fmid;

而(m_i似乎您的问题是由设计问题引起的。当您需要使用其他类的方法时,这可能意味着:

  • 这是一个“单一责任”原则的问题。类做得太多了。例如,数值方程求解算法是自给自足的实体,不应该是多项式的一部分。它们可以处理任何多项式
  • 继承树有一个问题。例如,应该创建一个公共祖先,并且公共方法应该在其中。请注意,如果您找不到该祖先的简短易懂的名称,那么这不是解决方案
  • 继承未正确使用。例如,我在代码中看不到虚拟方法,这很奇怪

  • 让我们更接近您的示例。您正在使用虚拟多重继承,这被认为是非常繁重的模式,通常不应该使用。此外,代码中没有虚拟方法,因此您实际上根本不使用继承。您要么必须放弃继承,要么考虑对所有c语言都有意义的常用方法类。对于函数,这似乎是一种在指定点计算函数值的能力。然后将所有不描述多项式或函数的代码移出类。移出数值解算器。这将允许在所有支持所需接口的类中重用它们。完全去掉Y类。似乎,这是必需的你不需要它,只要将funcA和funcB重命名为func,如果它们在语义上相同,并且对不同类型的多项式执行相同的操作。

    y=newy(N,i);
    --你在循环中创建了内存泄漏。@PaulMcKenzie我明白了,我做了
    y{N,1}
    ,然后使用了
    y.bla
    ,现在它可以工作了。但是,在我的程序中,我甚至没有做到这一点。
    m_c[]
    数组没有初始化。我不能只发布我所有的文件,因为已经有20多个文件了,简化意味着至少有5个文件。如果我显示错误会有帮助吗?请使用
    std::vector
    而不是原始指针(为什么要使用除明显的以外的所有文件?)一旦你这样做了,你会看到
    muc
    的大小是0,但是你在这里访问它:
    double out{static\u cast(muc[0])Jenkins Traub,它需要转换为C++,但有C风格的数组。我试着修改它,但它不仅崩溃了,而且至少需要两倍的时间来解决。所以我就让它……<代码> STATICEXCAST 是我的错,我做的时候剩下的。例如,使用
    int
    系数,然后我改为
    double
    ,忘记删除强制转换。我的错误。目标是首先让代码工作,从这一点来看,在确定可能的错误时,您似乎走错了路。向量指出您分配了0字节,并试图访问元素0。这就是
    std::out_of_range
    错误所说明的,也是我使用原始指针版本运行代码时崩溃的原因。我从继承开始,计划在类
    A
    B
    ,等中使用
    开关/case
    Y
    内部调用构造函数(它还处理输出到屏幕结果等),但我做不到,所以我切换到简单的成员函数,如
    funcA()
    。类本身是简单的,因为它们只创建多项式的类型,就是这样。类
    X
    保存变量,这些变量与
    A
    B
    等通用,类
    Y
    对所有内容进行预处理、打印、计算、计算,这就是“控制面板”尽管如此,你是对的,这很混乱,而且更糟……当类Y实现类A时,这意味着Y是A的一种特殊类型,可以做A能做的一切。因此,如果Y继承自A和B,那么它同时是A和B。在你的示例中,继承是“颠倒”使用的.所有通用函数必须在一个基中。它们可能是抽象的(具体实现由祖先提供),但它们必须在基中定义。我尝试过这样做,根查找算法位于顶部的
    X
    ,任何需要它的人都可以使用。假设是这样的:我需要一个多项式打印出来并在一个范围内求值。
    Y
    这样做,但使用哪一个呢?
    I
    是选择,它调用适当的多项式类,它只创建多边形。术语对于所有多边形类都是通用的,并且存储在
    X
    中。因此
    Y
    调用
    A
    (如果<