为啥我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例?

Posted

技术标签:

【中文标题】为啥我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例?【英文标题】:Why Can't I create an instance of a C++ class defined in the same namespace as the class definition?为什么我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例? 【发布时间】:2013-08-25 16:44:22 【问题描述】:

我的一个朋友正在学习 C++,我一直在帮助他。我们都在使用 Visual Studio 2010。

以下代码给出错误:

#include <iostream>
using namespace std;

namespace Characters

    class PlayerStats
        
        public:
            int HPMax, HPCurrent;
        ;
    PlayerStats John;
    John.HPMax = 1;
    Characters::John.HPMax = 1;

“PlayerStats John;”行似乎解决得很好,但是后面的行 (“John.HPMax = 1;”和“Characters::John.HPMax = 1;”) 给出错误“错误:此声明没有存储类或类型说明符” 以这种方式在命名空间内设置成员变量是非法的,还是我缺少其他东西?

【问题讨论】:

代码(我的意思是除了全局使用指令/声明和变量声明之外的语句)进入函数。 【参考方案1】:

命名空间内只允许声明。

这些

 John.HPMax = 1;
 Characters::John.HPMax = 1;

不是声明。

【讨论】:

您可以在命名空间中定义如下:cplusplus.com/doc/tutorial/namespaces @John Smith:我假设定义也是声明。这不总是对的吗? @JoséX.:我想说某处有一个单一的极端情况,但我想不出来,当然你说的一般是正确的。跨度> (cplusplus.com很基础,一般不会说清楚这些细节。) 是的,在 C++ 中,“定义”是“声明”的子类别。 (有时人们使用“声明”一词,就好像它排除了定义一样,这会导致混淆。但 José X. 使用的是一般和技术上正确的含义。)【参考方案2】:

赋值语句只允许在函数中使用(包括构造函数或析构函数作为特殊类型的函数)。大多数“可执行”语句都是如此。命名空间对此无关紧要。如果没有它们,或者在类或结构内部(但不在内联函数体中),这些分配将是非法的。

在函数之外只允许声明,所以如果你需要初始化 John 实例的那些成员,那么你必须使用某种初始化器。

由于该类(到目前为止)只有公共数据成员,没有构造函数或虚拟方法,因此您可以将成员初始化与花括号列表一起使用:

PlayerStats John = 2, 1; // sets HPMax=2 and HPCurrent=1

这种类通常被描述为结构,通常只用于非常小的、简单的对象。数据成员按照声明的顺序进行初始化。

更面向对象的方法是使用构造函数。 :

class PlayerStats

public:
    int HPMax, HPCurrent;
    PlayerStats(int max) : HPMax(max), HPCurrent(max) 
;

// define an instance of PlayerStats, with max HP of 1:
PlayerStats John(1);

如果您拥有或可以定义一个接受您需要初始化的信息的构造函数,那么这将起作用。您不能让两个不同的构造函数采用相同数量和类型的参数,因此构造函数必须是唯一一个只接受一个 int 作为其参数的构造函数。

还有其他方法,使用“工厂方法”或静态类初始化,但涉及更多。上面的内容应该可以让你暂时开始。

【讨论】:

【参考方案3】:

如果您需要定义全局变量 PlayerStats John,您可以将成员初始化推送到构造函数中。这样的事情会起作用:

namespace Characters

    class PlayerStats
    
    public:
        int HPMax, HPCurrent;
        PlayerStats( int hpm, int hpc ) : HPMax(hpm), HPCurrent(hpc)  
    ;
    PlayerStats John( 1, 1 );

【讨论】:

【参考方案4】:

这样做:

#include <iostream>
using namespace std;

namespace Characters

    class PlayerStats
        
        public:
            int HPMax, HPCurrent;
        ;


int main( void )

    Characters::PlayerStats John;
    John.HPMax = 1;
    return 0;

【讨论】:

以上是关于为啥我不能创建在与类定义相同的命名空间中定义的 C++ 类的实例?的主要内容,如果未能解决你的问题,请参考以下文章

XSLT 在与根元素具有相同命名空间声明的内部标记中缺少命名空间

为啥我不能从不同命名空间中的朋友类更改类的私有成员?

命名空间

不能在命名空间中使用自定义视图进行设计

C++ 命名空间 (namespace)

JAXB:为啥在生成的 xml 文档中未使用定义的命名空间前缀?