c++ - 具有一个成员的命名空间或类?

标签 c++ class oop namespaces encapsulation

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

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 文件中我声明了一个类的实例:

#include "canvas.h"

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

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

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

最佳答案

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

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

class Canvas final {

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

public:
  unsigned outerWidth, outerHeight;

}

我建议您也将 outerWidthouterHeight 声明为 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,这将是您的Canvas 类的一个实例。它可以从任何包含 "canvas.h" 包含文件的源中看到,而不仅仅是在您的 main() 例程中,因为它在您的示例片段中发布。

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

注意事项

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

关于c++ - 具有一个成员的命名空间或类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57944343/

相关文章:

c++ - 预处理器宏覆盖 C++ 中的函数定义

c++ - 使用 v4l2scr 重启 gstreamer 管道的正确方法

c++ - 我如何理解fdump-class-hierarchy输出

c# - 如何处理 C# 中缺少多重继承的问题

python - 如何检查字符串枚举中是否存在字符串?

matlab - 有没有办法找到一个 Matlab 类的所有 child ?

javascript - Crypto++ 低级 AES API(a la SJCL)

c++ - 是否可以测试两个迭代器是否指向同一个对象?

c++ - 在类定义中使用自定义结构

Python设计——初始化、设置和获取类属性