首先,我是C ++的初学者。其次,我很遗憾这篇文章太长了。我有一些相互使用的类,类似于这张图片(快速草图):
这是一个可用代码的快速草图。公式是假的,但功能接近真正的问题。为简单起见,我省略了制作源文件。 #includes
就像它们在最后一次编译后得到的错误最少......
" y.h"
#pragma once
#include "a.h"
#include "b.h"
class X;
class A;
class B;
class Y
{
private:
double m_y;
public:
Y(double b, double c):
{
if (c)
m_y = b*b;
else
m_y = sqrt(b);
if (b<0)
{
A::setP(m_y);
A::setQ(m_y + 1);
A::setR(m_y - 1);
}
else
{
B::setP(m_y);
B::setQ(m_y + 1);
B::setR(m_y - 1);
}
}
&#34; A.H&#34;
#pragma once
#include "x.h"
class X;
class A : virtual public X
{
private:
double m_p, m_q, m_r;
public:
A(double a, double b): m_p {a*a}
{
m_q = m_p + 0.5 * b;
m_r = m_q - m_p;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
&#34; b.h&#34;
#pragma once
#include "x.h"
class X;
class B : virtual public X
{
private:
double m_p, m_q, m_r;
public:
B(double a, double b): m_p {a + a}
{
m_q = m_p*m_p;
m_r = b + m_q;
}
void setP(double p) { m_p = p; }
void setQ(double q) { m_q = q; }
void setR(double r) { m_r = r; }
double getP() { return m_p; }
double getQ() { return m_q; }
double getR() { return m_r; }
};
&#34; x.h&#34;
//#include "a.h"
class A;
class B;
class X
{
private:
double m_x1, m_x2;
public:
X(double a, double b, double c, int d): m_x1 {2*a}
{
double p, q, r;
switch (d)
{
case 1:
p = A::getP();
q = A::getQ();
r = A::getR();
m_x2 = p * b + q * c - r;
break;
case 2:
p = B::getP();
q = B::getQ();
r = B::getR();
m_x2 = (p - q) * b + r / c;
break;
}
}
double getX1() { return m_x1; }
double getX2() { return m_x2; }
};
&#34;的main.cpp&#34;
#include "x.h"
#include <iostream>
int main()
{
X test {3.14, 0.618, 1.618, 1};
std::cout << test.getX1() << '\t' << test.getX2() << '\n';
return 0;
}
我的问题是必要的包含(假设每个类都有一个头文件和源文件)。现在,我们只考虑那里的A级。 main.cpp
只有#include x.h
。为了避免重复使用所有组合的代码,我将尝试枚举我到目前为止所做的事情:
#include a.h
,然后在类A中#include y.h
,类Y没有#include
,没有前向声明。编译器在Y和A中都抱怨expected class name before {
。
将前向声明添加到上面的=&gt; Y和A都有invalid use of incomplete type "class ..."
。
在Y类中使用#include a.h
向后执行,然后在A类中执行#include x.h
,类X没有#include
,前向声明=&gt; X类incomplete type A used in nested name spacifier
,指向X(): { int x {A::funcA()} }
。
如上所述,没有前瞻性声明意味着无处不在。
在网上搜索说这是因为循环依赖,但是怎么可能因为我只包括前一个或下一个,从不两者兼而有之?有答案说使用#pragma once
而不是通常可以解决问题,我试过,它是相同的incomplete type...
。仅供参考,我还尝试查看一些源代码(wxMaxima,大胆)以了解他们是如何做到的,并且似乎他们使用了我的第一种方法。
此时,我很困惑。如果以上内容可用于回答,有人可以就如何正确使用#includes
在这里给我一些指示吗?如果没有,请发表评论,如果需要,我会删除它。