类命名空间

Class namespace?

本文关键字:命名空间      更新时间:2023-10-16

是我还是C++中面向对象范式的实现缺少类命名空间的概念?

以下是我的意思的一个例子:

文档 { 页眉 {} 正文 {}

页脚 {} }

文档是可以具有页眉、正文和页脚的对象。

从外部命名空间处理此类对象及其元素的一种直接方法是

  • 公文
  • 文档::页眉
  • 文档::正文
  • 文档::页脚

有没有办法在不限制文档类定义的情况下C++实现这种命名结构?

1) 命名空间文档 { ... }

这种情况需要在其自己的命名空间中有一个对象类,并且使用 Document::D ocument 似乎是多余的和无意的。

2) 命名空间 文档 { 类 ... } typedef 文档::D ocument document;

这种情况给出了文档和文档::{part},在大小写中,敏感的语言可能看起来很奇怪且无关。

3) 类文档 { 类 ... };

这种情况需要在每个嵌套类的定义中包含文档标头,并且不允许使最终对象成为其部分的派生物,因为它们是在其自己的范围内定义的。

4) 类文档 { 类 ... };类文档:公共文档{}

这种情况接近预期,但需要额外的类和继承。

!理想情况下,我想要的是

namespace class Document {
class Header;
class Body;
class Footer;
class Document; // linked with the parent namespace as with its own name space
}
Document doc; // ok, resolves Document as a class
Document::{Part} docPart; // ok, resolves Document as namespace

.)有没有其他合理的方法可以在不产生不合理的额外费用的情况下实现预期目标?

我也不确定为什么这些琐碎的事情不是一种标准的方法。有什么具体原因吗?

---澄清---

为了解决提出的一些问题,

"有什么用?"1)通俗语言 2)从语言构造到对象的抽象模型的透明映射,反之亦然。

"为什么要从物体的各个部分推导出一个物体?"并非对象引入的每个实体都必须是其部分。例如,它可以是它的本质。例如:

文档 { 骨架{} 部件 { 页眉 {} 正文 {}

页脚 {

} } }

---抽象框架---

将对象视为一个模块,其定义可以使用外部符号并引入自己的一些符号以及自己的逻辑实体的定义,因为它们应该保持相关,因为它引入了它们。

---点---

整个模块是一个对象的定义。能够在没有任何额外的语言嘲笑的情况下使用它会很好。

=== 分辨率 ===

感谢您的反馈。

在C++有办法将命名空间名称链接到类之前,我想我会使用

对象名称{ ...Object {} } -> ObjectName::Object,ObjectName::Part

在这种情况下构造。它可能没有我想的那么短,但至少足够透明,没有额外的成本,并且可以与前向声明一起使用。

您的第三个选项 - 使用嵌套类声明/定义,将为您提供所需的理想范围分辨率(尽管它不会涉及单个命名空间)。

class Document 
{
public:
class Header
{
// Header class declaration here
};
class Body
{
// Body class declaration here
};
class Footer
{
// Footer class declaration here
};
// Document declaration here.
};

您对此选项的担忧是:

要求在每个嵌套类的定义中包含文档标头

是的 - 嵌套类与周围的类有着千丝万缕的联系,它们的实现将取决于周围类的定义,因为它包含嵌套类的定义。 这是不可避免的。

Dpesn不允许使最终对象成为其部分的派生物,因为它们是在自己的范围内定义的。

你试图做的事情似乎没有什么逻辑意义——你试图根据它自己的部分来定义某物,这是一个循环定义。 通过从页眉、正文或页脚派生文档,您想实现什么目的?

您问题的最后一行表明您发现所需的功能"微不足道",但在我看来和经验来看,这远非微不足道。由于语法相似性,您似乎将命名空间和类混为一谈,但它们是完全不同的概念。 您必须在脑海中将两者分开,除了一些范围效应和范围解析语法外,它们几乎没有重叠。 您的"文档"必须是命名空间和类。 选择一个;) (从技术上讲,实际上可以同时拥有命名空间文档和类文档,但这可能会造成混淆。 )

你的第一种情况完全按照你所说的去做。Document::Document没有什么多余的 - 它指的是Document命名空间中的Document类。XML命名空间中很可能有一个 Document 类,MyCompany命名空间中很可能有一个 Document 类。

第二种情况看起来像是试图从根本上破坏使用命名空间的目的。如果您不想使用命名空间,请不要 - 只需使用全局(未指定)命名空间并冒冲突的风险。如果只想避免代码中与Document类相关的Document::部分,请在该代码中添加using namespace Document指令。

您只需将零件类包含在Document类中即可。

class Document {
public:
class Header;
class Body;
class Footer;
};

您可以有效地使用它:

Document myDoc;   // Type Document
Document::Header myHeader;

3) class Document { class ... };

这种情况需要在每个嵌套类的定义中包含文档标头,并且不允许使最终对象成为其部分的派生物,因为它们是在其自己的范围内定义的。

不,这种设计是最有意义的。我不明白你认为classnamespace class之间的区别是什么.

class Document
{
public:
class Header
{
};
Header m_header;
class Body
{
};
Body m_Body;
};

这个设计有什么问题?您可以通过Document::Header访问这些类型。您可以通过myDocument.m_header等实例进行访问。

唯一固有的奇怪之处在于你不能将类型和成员变量命名为相同,但是有很多方法可以解决这个问题,这实际上是一个肤浅的限制。

仅仅因为Document对象包含Header对象并不意味着Header应该包含在Document中。至少,这通常不会这样做。

我只会在极少数情况下嵌套类;也就是说,当嵌套类是外部类的实现细节并且不向外部世界公开时(但即便如此,放弃嵌套也很常见)。

顺便说一下,这与C++无关:除了隐藏实现细节之外,类通常很少嵌套。像您一样,对对象关系进行建模的框架通常不会使用嵌套。相反,您可能有如下所示的内容:

namespace Html {
class Document;
class Header;
class Body;
// …
}

C++特别使用平面命名空间层次结构,但上述内容同样适用于 C# 或 Java。

最后,明确回答您的介绍性问题:

是我还是面向对象范式的实现C++缺少类命名空间的概念?

C+ 与其他现代 OO 语言具有相同的概念:类形成一个命名空间,用于名称查找,以便您可以实现所需的目标。但出于上述原因,我认为这不是一个特别理想的目标。

我不完全清楚你想公开多少嵌套的 类,但如果它们是Document的一部分,它们可能应该是 嵌套类。 你的意思的例子,在你的开头 代码,正是人们在C++中执行此操作的方式:

class Document
{
public:  //  or not?
class Header
{
};
class Body
{
};
class Footer
{
};
};

关于我能看到的唯一反对意见是仅实现文件 关注Document::Header必须包括整个Document类定义,但我认为这不是一个主要问题;如果Document::Header真的不是独立的,那么似乎合理 需要这个。 关于你对此解决方案的第二个反对意见: 你永远不想让一个对象从它的部件派生:一个Document哈斯·Header;这不是一种是关系

如果单独使用Header等人确实有意义,那么 最好的解决方案是在Document类之外定义它们,要么 赋予它们更具描述性的名称(例如DocumentHeader) 或包装 它们位于一个特殊的命名空间中(例如namespace DocumentParts)。 取决于 关于他们与Document的关系,使用可能是有意义的typedefDocument,以便它们可以称为DocumentParts::HeaderDocument::Header.