我在.h文件中有两个非常相似的类,它们在构造函数中需要彼此。它是一个Color类,一个将使用unsigned char 0到255作为RGB,另一个将使用浮点数0.0到1.0作为RGB,我需要能够在构造函数和赋值运算符以及其他成员函数中从一个和另一个转换。
Color3.h:
class Color3 {
public:
unsigned char R, G, B;
Color3()
: R(0), G(0), B(0) {
}
Color3(unsigned char r, unsigned char g, unsigned char b)
: R(r), G(g), B(b) {
}
Color3(const Color3f& other)
: R(other.R*255), G(other.G*255), B(other.B*255) {
}
};
class Color3f {
public:
float R, G, B;
Color3f()
: R(0), G(0), B(0) {
}
Color3f(float r, float g, float b)
: R(r), G(g), B(b) {
}
Color3f(const Color3& other)
: R(other.R/255), G(other.G/255), B(other.B/255) {
}
};
我可以将它们放在单独的文件中而不进入循环(我相信它是如何被称为)包含?我想我知道这个问题的答案,但我想知道其他解决方案可能在那里。我希望他们在同一个文件中,但如果没有别的办法,我会将它们分开。
答案 0 :(得分:4)
是
class Color3f; // <--- Forward declaration
class Color3
{
public:
unsigned char R, G, B;
Color3()
: R(0), G(0), B(0)
{
}
Color3(unsigned char r, unsigned char g, unsigned char b)
: R(r), G(g), B(b)
{
}
// Can't define this yet with only an incomplete type.
inline Color3(const Color3f& other);
};
class Color3f
{
public:
float R, G, B;
Color3f()
: R(0), G(0), B(0)
{
}
Color3f(float r, float g, float b)
: R(r), G(g), B(b)
{
}
Color3f(const Color3& other)
: R(other.R/255), G(other.G/255), B(other.B/255)
{
}
};
// Color3f is now a complete type, so define the conversion ctor.
Color3::Color3(const Color3f& other)
: R(other.R*255), G(other.G*255), B(other.B*255)
{
}
答案 1 :(得分:0)
这些情况是“pragma once”的用途。只需将其添加到.h文件的顶部,它将只包含一次:
#pragma once
但是,请确保它只是一个'include'循环,而不是实际的功能循环。看起来你的构造函数实际上可能会在实例化时导致我循环。
答案 2 :(得分:0)
您可以在头文件的顶部添加另一个类的声明,以避免循环依赖问题。例如:
class Color3;
位于Color3f.h
的顶部,同样适用于其他类。结合#pragma once
或#ifndef
包括防护,程序可以使用拆分文件进行编译。
但是类似的类应该真正声明为具有不同模板参数的同一个类。例如Color3<unsigned char>
和Color3<float>
。