是我还是C ++中面向对象范式的实现缺少类命名空间的概念?
这是我的意思的一个例子:
文档{标题{}正文{}页脚{}}
Document是一个可以有标题,正文和页脚的对象。
从外部名称空间处理此类对象及其元素的直接方法是
有没有办法在C ++中实现这样的命名结构而不对Document类的定义施加限制?
1)namespace Document {...}
这种情况需要在其自己的命名空间内使用对象类,并且使用Document :: Document似乎是多余的和无意的。
2)namespace Document {class ...} typedef Document :: Document document;
本案例给出了文档和文档:: {part},以防敏感语言看似奇怪且无关。
3)class Document {class ...};
这种情况要求在每个嵌套类的定义中包含Document头,并且不允许使最终对象成为其部分的衍生物,因为它们是在自己的范围内定义的。
4)班级文件{class ...}; class Document:公共文档{}
这种情况接近预期,但需要额外的类和继承。
!)理想情况下,我想拥有的是
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)从语言构造到对象抽象模型的透明映射,反之亦然。
“为什么要从其各个部分派生一个对象?”并非对象引入的每个实体都必须是它的一部分。例如,它可能是它的本质。 E.g:
文档{Skeleton {} Parts {Header {} Body {} Footer {}}}
---抽象框架---
将一个对象想象成一个模块,它的定义可以使用外部符号,并引入它自己的一些符号以及它自己的逻辑实体的定义,因为它们引入它们应该保持相关。
---点---
整个模块是对象的定义。如果没有任何额外的语言嘲笑,能够使用它会很好。
=== resolution ===
感谢您的反馈。
直到C ++中有一种方法将命名空间名称链接到一个类,我想我会用
ObjectName {... Object {}} - > ObjectName :: Object, ObjectName :: Part
在这种情况下构建。它可能没有我想要的那么短,但至少足够透明,没有额外费用,并且可以与前向声明一起使用。
答案 0 :(得分:6)
您的第三个选项 - 使用嵌套类声明/定义,将为您提供理想的范围解析(尽管它不涉及单个命名空间)。
class Document
{
public:
class Header
{
// Header class declaration here
};
class Body
{
// Body class declaration here
};
class Footer
{
// Footer class declaration here
};
// Document declaration here.
};
您对该选项的担忧是:
要求在每个嵌套类的定义中包含Document标头
是 - 嵌套类与周围的类密不可分,它们的实现将取决于周围类的定义,因为它包含嵌套类的定义。这是不可避免的。
Dpes不允许使最终对象成为其各部分的衍生物,因为它们是在自己的范围内定义的。
你要做的事似乎没有什么逻辑意义 - 你试图根据自己的部分定义一些东西,这是一个循环的定义。你想通过从页眉,正文或页脚派生文件来实现什么目标?
你问题的最后一行表明你发现你想要的功能“微不足道”,但在我看来,这并不是微不足道的。由于语法上的相似性,您似乎在混淆命名空间和类,但它们是完全不同的概念。您必须将两者分开,除了一些范围效果和范围分辨率语法之外,它们几乎没有重叠。您的“文档”必须是命名空间和类。选择一个;)(从技术上讲,它实际上可能同时具有命名空间Document和类Document,但这很可能是混乱的根源。 )
答案 1 :(得分:2)
你的第一个案件正是你所说的。 Document::Document
没有任何多余的内容 - 它引用Document
命名空间中的Document
类。 XML
命名空间中可能有一个Document类,而MyCompany
命名空间中可能有另一个。
你的第二个案例看起来像是试图破坏使用命名空间的目的。如果您不想使用命名空间,请不要 - 只使用全局(未指定)命名空间和风险冲突。如果您只想避免与Document::
类相关的代码中的Document
部分,请在该代码中添加using namespace Document
指令。
答案 2 :(得分:1)
3)class Document {class ...};
这种情况要求在每个嵌套类的定义中包含Document头,并且不允许使最终对象成为其部分的衍生物,因为它们是在自己的范围内定义的。
不,这种设计是最有意义的。我不明白您认为class
和namespace class
之间存在差异。
class Document
{
public:
class Header
{
};
Header m_header;
class Body
{
};
Body m_Body;
};
这个设计有什么问题?您可以通过Document::Header
访问这些类型。您可以通过myDocument.m_header
等实例进行访问。
唯一固有的奇怪之处在于你不能将类型和成员变量命名为相同,但是有很多方法可以解决这个问题,而且这实际上是一种肤浅的限制。
答案 3 :(得分:1)
您只需将部分类括在Document
类中。
class Document {
public:
class Header;
class Body;
class Footer;
};
您可以有效地使用它:
Document myDoc; // Type Document
Document::Header myHeader;
答案 4 :(得分:1)
仅仅因为Document
对象包含Header
对象并不意味着Header
类< / em>应包含在Document
类中。至少,通常不会这样做。
我只会在极少数情况下嵌套类;也就是说,当嵌套类是外部类的实现细节时,并且不暴露给外部世界(但即使这样,放弃嵌套也是常见的)。
顺便说一句,这与C ++无关:除了隐藏实现细节之外,通常很少嵌套类。在您的情况下建模对象关系的框架通常不会使用嵌套。相反,你可能会有这样的事情:
namespace Html {
class Document;
class Header;
class Body;
// …
}
C ++特别使用平面命名空间层次结构,但上述内容同样适用于C#或Java。
最后,要明确地解决您的介绍性问题:
是我还是C ++中面向对象范式的实现缺少类命名空间的概念?
C +与其他现代OO语言具有相同的概念:一个类形成一个命名空间,用于名称查找,因此可以实现你想要的。但由于上述原因,我认为这不是一个特别理想的目标。
答案 5 :(得分:0)
我不清楚你想要暴露多少嵌套
类,但如果它们是Document
的一部分,它们可能应该是。{1}}
嵌套类。你的意思的例子,在你的开始
代码,正是人们如何在C ++中做到这一点:
class Document
{
public: // or not?
class Header
{
};
class Body
{
};
class Footer
{
};
};
关于我能看到的唯一反对意见仅是实施文件
与Document::Header
有关的问题必须包括整个Document
类定义,但我不认为这是一个主要问题;如果
Document::Header
真的不是独立的,那么它似乎是合理的
需要这个。关于您对此解决方案的第二个异议:
你永远不想让一个对象来自它的部分:Document
hasA Header
;它不是 isA 的关系。
如果将Header
等单独使用确实有意义,那么
最好的解决方案是在Document
类之外定义它们
为他们提供更具描述性的名称(例如DocumentHeader
)或包装
它们位于特殊的命名空间中(例如namespace DocumentParts
)。根据
关于他们与Document
的关系,使用它可能是有意义的
typedef
中的Document
,以便将其称为“{1}}
DocumentParts::Header
或Document::Header
。