类命名和命名空间

时间:2009-10-04 16:05:48

标签: c++ oop namespaces

在多个名称空间中使用相同的类名会让我遇到麻烦吗?我也尝试删除对数学库的依赖。您如何看待设计。

第一个文件

#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);
    };
}

修改

这种删除依赖的方法怎么样?

**第一档**

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);
    };
}

提前致谢。

2 个答案:

答案 0 :(得分:3)

我没有看到在不同名称空间中重复使用相同标识符的问题,就是它们毕竟是为它们创建的。

但是我强烈建议你不要'模拟'包含math :: Rectangle。如果您需要该文件然后包含它,但您正在做的是称为复制/粘贴编程,它会导致大量问题,主要是因为您的两段代码未同步所以任何错误修复/功能添加到一个另一方没有报道。

编辑:回答编辑;)

评论中不清楚所以我会说明:

如果您需要依赖项(因为您确实使用了所提供的功能),那么您必须包含标头。另一方面,如果你只使用继承来获得具有4个角并且几乎没有方法的东西,那么你最好滚动一个具有最小功能的新Rectangle类。

我可以想到一个边缘案例。我的印象是你对功能并不是那么感兴趣,但实际上对重新使用Math库中的方法感兴趣,这些方法已被定制为将math :: Rectangle作为参数。

根据Herb Sutter(我认为在C ++编码标准中),与类捆绑在一起的自由函数是类公共接口的一部分。所以如果你想要这些类,你实际上需要继承。


现在我可以理解你可能不愿意加入一个可能很大的库(我不懂你的数学库)。在这种情况下,您可以考虑将Math库分成两部分:

  • MathShapes库,包含基本形状和作用于它们的方法
  • 数学库,包括MathShapes并添加所有其他内容

这样你只依赖于MathShapes库。

另一方面,如果你绝对不想要依赖,那么一个钝的复制/粘贴就行了,但你通过测试它的头部防护的存在来测试Math :: Rectangle的存在的解决方案是不合适的:

  • 只有正确获得标题后卫才会有效
  • AND 如果包含实际执行 BEFORE 包含Graphics :: Rectangle

请注意,在Math :: Rectangle之前包含Graphics :: Rectangle的情况下,您可能会遇到一些编译问题......

所以请考虑一下你是否想要依赖。

答案 1 :(得分:2)

这就是命名空间的用途,矩形既是数学对象又是图形对象。

但是,避免包含头文件的尝试是非常不明智的。它除了维持头痛外什么都没有。 math :: Rectangle 中的更改应该导致重建图形:: Rectangle - 如果它们最终出现不匹配并且您将其隐藏在编译器中,您将最终难以调试运行时间错误。