Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 名称空间或具有一个成员的类?_C++_Class_Oop_Namespaces_Encapsulation - Fatal编程技术网

C++ 名称空间或具有一个成员的类?

C++ 名称空间或具有一个成员的类?,c++,class,oop,namespaces,encapsulation,C++,Class,Oop,Namespaces,Encapsulation,我在主机上做一个小游戏,遇到了一个小问题。假设我有一个名为Canvas的类: canvas.h class画布最终版{ 公众: //建造师 画布(无符号宽度=10,无符号高度=30); 未签名的外径、外径; } canvas.cpp #包括“canvas.h” 画布::画布(无符号宽度、无符号高度){ 外径=宽度; 外光=高度; //我在这里画了一个盒子(画布)的边框 } 现在,在main.cpp文件中,我声明了该类的一个实例: #包括“canvas.h” //节目从这里开始 int mai

我在主机上做一个小游戏,遇到了一个小问题。假设我有一个名为
Canvas
的类:

canvas.h

class画布最终版{
公众:
//建造师
画布(无符号宽度=10,无符号高度=30);
未签名的外径、外径;
}
canvas.cpp

#包括“canvas.h”
画布::画布(无符号宽度、无符号高度){
外径=宽度;
外光=高度;
//我在这里画了一个盒子(画布)的边框
}
现在,在
main.cpp
文件中,我声明了该类的一个实例:

#包括“canvas.h”
//节目从这里开始
int main(){
帆布我的帆布;
返回0;
}
首先,我希望只有
Canvas
类的一个成员,因为我的程序就是这样设计的。但是,当我创建该类的实例时,它会得到一个名称(
myCanvas
)。然后,如果我想要另一个使用画布的类(比如说,
Entity
),我必须说
myCanvas.outerWidth
,这取决于对象的名称。另外,我认为无论如何,
myCanvas
变量在此类范围内都是不可用的


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

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

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

我还建议您将
outerWidth
outerHeight
声明为
const
,如果它们将由类公开,那么您不能修改它们(使实例不可变)或声明访问器方法来访问这些字段,并声明
公共
静态
字段
实例
(或
CANVAS
),如中所示:

您可以在
.cc
文件中使用以下命令对其进行实例化:

#include <canvas.h>
...
Canvas Canvas::instance;  // by default 10 by 10, this is the public available instance declared above.
...
#包括
...
Canvas Canvas::instance;//默认情况下是10乘10,这是上面声明的公共可用实例。
...
通过这种方式,您可以在任何地方使用
Canvas::instance
,这将是
Canvas
类的一个实例。它将从包含
“Canvas.h”
包含文件的任何源中可见,而不仅仅是在
main()
例程中,就像您发布的示例代码片段中一样

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


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

创建头文件,不要使用<代码>类< /C> >,使用<代码>命名空间< /代码>,此外,使用匿名命名空间使您想要的代码<代码>私下<代码>具有内部链接。@ MrRasimi考虑使用“代码>静态< /COD>方法”的一些示例。吨类的暗示。它们会提醒你一些东西吗?是的,语法与使用命名空间而不是类时使用的语法完全相同。因此,我相信在C++中不应该使用单级类,而如果需要单体行为,则使用命名空间。@ FureeSyIn,语法不相同。在类声明中允许不同的访问控制级别。此外,singleton仍然是一个singleton,无论它使用的是自由函数还是某个类的成员函数。@VTT我应该指定我所指的是调用语法。它们本质上是相同的。是的,但是我如何在命名空间中创建只读变量(文件外读访问,文件内读写访问)?我需要创建一个只能初始化一次的常量
width
变量。我看不到任何使用名称空间的简单方法。关于outerWidth和outerHeight变量,我希望它们是常量,但稍后声明(在构造函数中绘制画布时)还有,关于构造函数,我想在main函数中指定宽度和高度,然后在类方法中将它们复制到outerWidth和outerHeight变量中。基本上,我希望所有(或大部分)画布属性不可从外部修改,而是在Canvas::draw()中定义我还没有测试过这个,但我认为它会起作用。不管怎样,我会把这个答案标记为正确的。对不起,但由于你只发布了部分代码,我不可能提供丢失的代码,也不会误解你的意图……下次
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

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