假設我有一大堆的繼承類的這樣的使用成員函數:C++從類似的虛擬公共類
...他們都成爲製作各種多項式的目的。 X
類主要是變量坦克,類A
,B
等都是virtual public X
,每個創建ont類型的多項式,類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
:
X::funcX()
是一個簡單的求根算法被稱爲超過一個virtual public
類(A
,B
等)。 m_c
,m_n
,m_w
是共享變量。
類A
和B
:
它們的主要功能是funcA()
(和funcB()
,等等),並創建多項式(在體內,有一個for
循環),根據計算出的順序,X::m_n
上。評估多項式爲A::calcA()
。這也需要由class B
調用,或者重新定義。由於代碼膨脹,我寧願避免後者。它也不會找我相當初級水平非常「專業」 ......
類Y
這就要求任何根據的說法i
(該switch/case
)的virtual public
類。
該代碼編譯,但崩潰。它打印案件。這個例子指向A::funcA()
作爲罪魁禍首,但在原始程序中,我可以看到係數m_c[i]
甚至沒有使用動態內存進行初始化,如試圖打印出m_c[0]
崩潰。我試圖移動new double[]
insode函數A
,但這不起作用。
我不知道該怎麼做。這是否有意義,有可能嗎?如果是,如何?
編輯:忘了補充一點,我不能隨便動calcA()
從A
頂端,在X
,因爲每一個多項式不同的評估,因爲有捷徑,變化,在每一個,使得它可能對每個多項式進行不同的優化評估。我可以讓X::calcA()
成爲一個普遍的,但會有一個表現懲罰,我寧願不支付。
'y = new Y(N,i);' - 您正在循環中創建內存泄漏。 – PaulMcKenzie
@PaulMcKenzie我現在看到了,我做了'Y y {N,1}',然後使用'y.bla',現在它工作。但是,在我的程序中,我甚至沒有到達那裏。 'm_c []'數組沒有被初始化。由於已有超過20個文件,因此我不能只發布所有內容,而簡化將意味着至少有5個文件。如果我顯示錯誤會有幫助嗎? –
請使用'std :: vector'而不是原始指針(爲什麼除了明顯的使用其他所有東西?)。一旦你這樣做,你會發現'm_c'的大小爲0,但是你在這裏訪問它:'double out {static_cast(m_c [0])};'。 [看到這裏](http://ideone.com/TcjUPx) –
PaulMcKenzie