一个成员的命名空间或 class?

Namespace or class with one member?

我正在控制台中制作一个小游戏,遇到了一个小问题。假设我有一个名为 Canvas:

的 class

canvas.h

class Canvas final {

public:
  // Constructor
  Canvas(unsigned width = 10, unsigned height = 30);

  unsigned outerWidth, outerHeight;

}

canvas.cpp

#include "canvas.h"

Canvas::Canvas(unsigned width, unsigned height) {
  outerWidth = width;
  outerHeight = height;

  // I draw a box (canvas)'s border here
}

现在在 main.cpp 文件中声明 class:

的一个实例
#include "canvas.h"

// The program starts here
int main() {
  Canvas myCanvas;
  return 0;
}

首先,我希望 Canvas class 中只有 1 个成员,因为我的程序就是这样设计的。但是,当我创建 class 的实例时,它会获得一个名称(本例中为 myCanvas)。然后,如果我想要另一个使用 canvas 的 class(比方说,Entity),我必须说 myCanvas.outerWidth,这取决于对象的名称。此外,我认为 myCanvas 变量无论如何都不会在此类 class 的范围内可用。

另一方面,当我使用名称空间时,我失去了使用 classes(封装(私有属性)、构造函数)的一些好处。那我该怎么办?制作静态 class 或命名空间还是什么?我听说在 C++ 中没有称为静态 class 的东西;只有静态属性或方法。我想把 static 关键字放在任何地方都不是好的做法。或者是?

如果您想要单个实例(我猜您想要单个实例,而不是单个成员,因为成员是 class 的组件字段之一,因此,您的 class 现在有两个成员字段)你可能在谈论 单例模式 (一个 class 只有一个实例并且无法实例化另一个实例)。

只需声明构造函数 privateprotected,这样客户端代码就无法创建该对象的第二个实例。在这种情况下,您只能使用已经为客户端代码生成的实例,而客户端代码无法获取新实例(通过 new 运算符或在 main() 中声明实例)。

class Canvas final {

  // Constructor now is private
  Canvas(unsigned width = 10, unsigned height = 30);

public:
  unsigned outerWidth, outerHeight;

}

如果 outerWidthouterHeight 要被 class 公开,我建议您也将它们声明为 const,这样您就无法修改它们(使实例不可变)或声明访问器方法以访问这些字段并声明 publicstatic 字段 instance(或 theCanvas),如:

class Canvas final {

  // Constructor
  Canvas(unsigned width = 10, unsigned height = 30);

public:
  unsigned outerWidth, outerHeight;
  static Canvas instance;  // we have a static instance defined elsewhere

}

您可以在 .cc 文件中实例化它:

#include <canvas.h>
...
Canvas Canvas::instance;  // by default 10 by 10, this is the public available instance declared above.
...

这样,你就可以在任何地方使用Canvas::instance,那将是你Canvasclass的一个实例。它可以从任何包含 "canvas.h" 包含文件的源中看到,而不仅仅是在您的 main() 例程中,就像在您 post.

的示例片段中一样

顺便说一句,如果您只在私有代码中使用一次构造函数,那么声明带参数的构造函数没有多大意义。也不需要声明默认参数值,但是你妨碍了。你来决定。

备注

由于不完全清楚你在尝试什么,我可能误解了你的意图,所以如果这不是你想要的,请不要怪我,并编辑你的问题以使你的目标更清楚。您已将 outerWidthouterHeight 声明为非 const,因此,它们可以被任何有权访问它们的代码修改。目前尚不清楚您是否希望您的实例不可变(实例化后不可修改),也不清楚它们是否必须从某些外部代码中获取它们的值。