类命名和命名空间
在多个命名空间中使用相同的类名会使我陷入麻烦吗?我也试着去除依赖到数学库。你怎么看待下面的设计。类命名和命名空间
第一个文件
#define MATH_RECTANGLE_EXISTS
namespace math {
class Rectangle : Object2D {
public:
float perimeter();
float area();
float x,y,w,h;
};
}
其他文件
#define GRAPHIC_RECTANGLE_EXISTS
#ifndef MATH_RECTANGLE_EXISTS
//is this a good idea to remove dependency?
namespace math {
class Rectangle {
public:
float x,y,w,h;
}
}
#endif
namespace graphics {
class Rectangle : math::Rectangle {
public:
void Draw(Canvas &canvas);
void Translate(float x, float y);
};
}
编辑
怎么样这种方法来删除依赖?
** 1 **文件
namespace common {
class Rectangle {
float x,y,w,h;
};
}
数学库文件
#define MATH_RECTANGLE_EXISTS
namespace math {
class Rectangle : public common::Rectangle, public Object2D {
public:
float perimeter();
float area();
};
}
图形文件
#define GRAPHIC_RECTANGLE_EXISTS
namespace graphics {
#ifndef MATH_RECTANGLE_EXISTS
class Rectangle : public math::Rectangle {
#else
class Rectangle : public common::Rectangle {
#endif
public:
void Draw(Canvas &canvas);
void Translate(float x, float y);
};
}
在此先感谢。
我看不到在不同名称空间中重复使用相同标识符的问题,毕竟这是他们创建的。
但是,我强烈要求你不要'模拟'包含数学::矩形。如果你需要这个文件然后包含它,但是你所做的就是复制/粘贴编程,并且会导致很多问题,这主要是因为你的两段代码没有同步,所以任何错误修复/功能添加到一个不在另一方报告。
编辑:答案编辑)
它不是从注释清楚,所以我会说明它:
如果你需要的依赖(因为你真的可以使用所提供的功能),那么你必须包含标题。另一方面,如果你只使用继承来获得具有4个角并且几乎没有方法的东西,那么你最好使用最小功能来滚动一个新的Rectangle类。
虽然我可以想到一个边缘案例。我的印象是,你对功能没有太大的兴趣,但实际上对重用Math库中的方法感兴趣,这些方法已经被定制为将数学::矩形作为参数。
根据Herb Sutter(我认为在C++编码标准中),捆绑在一个类中的免费函数是类公有接口的一部分。所以如果你想要这些类,你实际上需要继承。
现在我可以理解,你可能有一些不情愿包含一个可能很大的库(我不知道你的数学库)。在这种情况下,你可以考虑分为二的数学库:
- 一个MathShapes库,包括基本形状,并在他们身上充当
- 数学库,其中包括MathShapes和方法添加所有其他的东西
这样你只能依赖MathShapes库。另一方面,如果你绝对不想依赖,那么钝的复制/粘贴将会执行,但是通过测试它的头部保护的存在来测试Math :: Rectangle的存在的解决方案是不合理的,安装:
- ,如果你正确地获得头文件保护
- 和如果包括实际执行前的包括图形::矩形
请注意,在Math :: Rectangle之前包含Graphics :: Rectangle的情况下,您可能会遇到一些编译问题...
因此,请确定是否需要依赖关系。
这就是命名空间的用途,矩形既是数学对象也是图形对象。
但是,尝试避免包含头文件是非常不明智的。除维护令人头疼之外,它只能达到目的。数学中的变化::矩形应该会导致重建graphics :: Rectangle - 如果它们以不匹配的方式结束,并且将其从编译器中隐藏起来,则最终将更难以调试运行时错误。
是的,我意识到这一点,但我不想要两个库之间的依赖关系,而我想在它存在时使用它的功能。 – 2009-10-04 16:32:44
我已经更新了这个问题,你能否再次检查一下,thx。 – 2009-10-04 16:37:45
然后你应该使用某种接口/工厂。如果数学库可用,则可以从中取出实现,否则将使用替换。 – sdg 2009-10-04 16:38:34