![](/img/trans.png)
[英]C++: How can I make two classes declared on the same .cpp “see” each other at compile time?
[英]I have two classes that need to reference each other in the same cpp file, but the first one won't recognize objects of the second class type
編譯器給我:“變量的類型為rotation2d不完整”
class translation2d
{
public:
double x;
double y;
translation2d()
{
x=0;
y=0;
}
translation2d rotateBy(rotation2d rotation) //issue here
{
translation2d copy=*this;
copy=translation2d(x*rotation.cosM()-y*rotation.sinM(), x*rotation.sinM() + y*rotation.cosM());
return copy;
}
};
double kEpsilon = 0.000000009;
class translation2d;
class rotation2d
{
public:
double cosAngle;
double sinAngle;
public:
rotation2d()
{
cosAngle=1;
sinAngle=0;
}
rotation2d(translation2d& direction, bool norm)
{
cosAngle=direction.x;
sinAngle=direction.y;
if(norm)
normalize();
}
double cosM()
{
return cosAngle;
}
double sinM()
{
return sinAngle;
}
double tanM()
{
if(abs(cosAngle)<kEpsilon)
{
if(sinAngle>=0.0)
return std::numeric_limits<double>::infinity();
else
return -1*std::numeric_limits<double>::infinity();
}
return sinAngle/cosAngle;
}
}
為了解決 C++ 中的循環依賴,發明了前向聲明。
不知何故,OP 嘗試過,但方式錯誤。
因此,如果
class translation2d
需要class rotation2d
和
class rotation2d
需要class translation2d
第二個必須在第一個之前向前聲明。
struct rotation2d; // forward declaration -> incomplete type
struct translation2d {
void doSomethingWith(rotation2d rot);
};
struct rotation2d {
void doSomethingWith(translation2d trans);
};
前向聲明使類型不完整。 不完全類型在可以用它們做什么方面受到限制。
不完整類型的大小和內容均未知。 因此,編譯器拒絕所有需要這樣做的內容,例如
允許使用不完整的類型
我必須承認,我不知道后者,但發現:
SO:不完整的類型作為函數參數和返回值
為了我的啟蒙。
請注意,函數聲明的參數可能不完整,但函數定義的參數不完整。 因此,修復的第二部分是在函數中需要不完整的類型時使函數非內聯。
struct rotation2d; // forward declaration -> incomplete type
struct translation2d {
void doSomethingWith(rotation2d rot);
};
struct rotation2d {
void doSomethingWith(translation2d trans)
{
trans; // will be processed somehow
}
};
// now both types are complete
void translation2d::doSomethingWith(rotation2d rot)
{
rot; // will be processed somehow
}
OP修復完成的示例代碼:
#include <iostream>
#include <limits>
#include <cmath>
class rotation2d; // forward declaration
class translation2d
{
public:
double x;
double y;
translation2d()
{
x=0;
y=0;
}
translation2d(double x, double y): x(x), y(y) { }
translation2d rotateBy(rotation2d rotation); //issue here fixed
};
double kEpsilon = 0.000000009;
class rotation2d
{
public:
double cosAngle;
double sinAngle;
public:
rotation2d()
{
cosAngle=1;
sinAngle=0;
}
rotation2d(const translation2d& direction, bool norm)
{
cosAngle=direction.x;
sinAngle=direction.y;
if(norm)
normalize();
}
double cosM()
{
return cosAngle;
}
double sinM()
{
return sinAngle;
}
double tanM()
{
if(abs(cosAngle)<kEpsilon)
{
if(sinAngle>=0.0)
return std::numeric_limits<double>::infinity();
else
return -1*std::numeric_limits<double>::infinity();
}
return sinAngle/cosAngle;
}
void normalize()
{
const double len = std::sqrt(cosAngle * cosAngle + sinAngle * sinAngle);
cosAngle /= len; sinAngle /= len;
}
};
// both types complete now -> circular dependency resolved
translation2d translation2d::rotateBy(rotation2d rotation)
{
translation2d copy=*this;
copy=translation2d(x*rotation.cosM()-y*rotation.sinM(), x*rotation.sinM() + y*rotation.cosM());
return copy;
}
int main()
{
translation2d t(1.0, 2.0);
rotation2d r(translation2d(0.0, 1.0), false);
translation2d tR = t.rotateBy(r);
std::cout << "tR: (" << tR.x << ", " << tR.y << ")\n";
}
輸出:
tR: (-2, 1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.