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