0

それは私ですか、それとも C++ でのオブジェクト指向パラダイムの実装にクラス名前空間の概念がありませんか?

これが私が意味することの例です:

ドキュメント { ヘッダー {} 本文 {} フッター {} }

ドキュメントは、ヘッダー、ボディ、およびフッターを持つことができるオブジェクトです。

そのようなオブジェクトとその要素を外部名前空間からアドレス指定する簡単な方法は次のとおりです。

  • 書類
  • ドキュメント::ヘッダー
  • ドキュメント::本文
  • ドキュメント::フッター

Document クラスの定義に制限を課すことなく、C++ でそのような命名構造を実現する方法はありますか?

1) 名前空間ドキュメント { ... }

このケースでは、独自の名前空間内にオブジェクト クラスが必要であり、Document::Document の使用は冗長で意図的ではないようです。

2) 名前空間 Document { class ... } typedef Document::Document document;

この場合、ドキュメントと Document::{part} が与えられますが、センシティブな言葉が奇妙で無関係に見える場合があります。

3) クラス ドキュメント { クラス ... };

この場合、ネストされたすべてのクラスの定義に Document ヘッダーを含める必要があり、最終的なオブジェクトをその部分の派生物にすることはできません。それらは独自のスコープ内で定義されているためです。

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++ で名前空間名をクラスにリンクする方法ができるまでは、

ObjectName { ... Object {} } -> ObjectName ::Object, ObjectName :: Part

このような場合に構築します。私が望むほど短くはないかもしれませんが、少なくとも十分に透過的で、追加コストがなく、前方宣言で使用できます。

4

6 に答える 6

6

Your third option - using nested class declarations / definitions, will get you the ideal scope resolution as you want (though it will not involve a single namespace).

class Document 
  {
  public:
    class Header
      {
      // Header class declaration here
      };

    class Body
      {
      // Body class declaration here
      };

   class Footer
      {
      // Footer class declaration here
      };

    // Document declaration here.
  };

Your concerns with that option are:

Requires including Document header in definition of every nested class

Yes - the nested classes are inextricably linked to the surrounding class, their implementations will depend on the definition of the surrounding class because it contains the definitions of the nested classes. This is unavoidable.

Dpesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.

What you are trying to do seems to make very little logical sense - you are trying to define something based on its own parts, which is a circular definition. What are you trying to achieve by deriving Document from Header, Body or Footer?

The final line of your question suggests that you find your desired functionality "trivial", but in my opinion and experience it is far from trivial. You seem to be conflating a namespace and a class because of syntactical similarities, but they are entirely different concepts. You have to separate the two in your mind, they have very little overlap besides some scoping effects and scope resolution syntax. Your "Document" must be either a namespace and a class. Pick one ;) (technically it's actually possible to have both a namespace Document and a class Document, but this is likely to be a source of confusion. )

于 2012-09-25T09:26:20.867 に答える
2

あなたの最初のケースは、あなたが望んでいることを正確に実行します。冗長なことは何もありません。名前空間内のクラスをDocument::Document参照しています。名前空間には Document クラスがあり、名前空間には別のクラスが存在する可能性があります。DocumentDocumentXMLMyCompany

2番目のケースは、名前空間を使用する目的を本質的に無効にする試みのように見えます. 名前空間を使用したくない場合は、グローバルな (未指定の) 名前空間を使用して衝突の危険を冒してください。Document::クラスに関連するコードの部分だけを避けたい場合は、そのコードにディレクティブをDocument追加します。using namespace Document

于 2012-09-25T09:29:58.610 に答える
1

オブジェクトにDocument オブジェクトが含まれているからといって、クラスがクラスに含まれている必要があるわけではありません。少なくとも、それは通常は行われません。Header Header Document

クラスをネストするのはまれなケースだけです。つまり、ネストされたクラスが外側のクラスの実装の詳細であり、外部の世界に公開されていない場合です (ただし、その場合でも、ネストを控えるのが一般的です)。

ところで、これは C++ とは無関係です。クラスは一般に、実装の詳細を非表示にする場合を除いて、ネストされることはめったにありません。あなたの場合のようにオブジェクト関係をモデル化するフレームワークは、通常、ネストを使用しません。代わりに、次のようなものがあるかもしれません:

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

特に C++ はフラットな名前空間階層を使用しますが、上記は C# または Java にも同様に適用されます。

最後に、導入の質問に明示的に対処するには:

それは私ですか、それとも C++ でのオブジェクト指向パラダイムの実装にクラス名前空間の概念がありませんか?

C+ には、他の最新の OO 言語と同じ程度にこの概念があります。クラスは、名前の検索を目的として名前空間を形成し、目的を達成できるようにします。しかし、上記の理由から、それは特に望ましい目標ではないと思います。

于 2012-09-25T09:50:09.853 に答える
1

3) クラス ドキュメント { クラス ... };

この場合、ネストされたすべてのクラスの定義に Document ヘッダーを含める必要があり、最終的なオブジェクトをその部分の派生物にすることはできません。それらは独自のスコープ内で定義されているためです。

いいえ、このデザインは最も理にかなっています。classと の違いが何だと思うかわかりませんnamespace class

class Document
{
public:
    class Header
    {
    };

    Header m_header;

    class Body
    {
    };

    Body m_Body;
};

このデザインの何が問題なのですか?を介してタイプにアクセスしますDocument::Header。のようなインスタンスを介してアクセスしますmyDocument.m_header

固有の唯一の奇妙さは、型とメンバー変数に同じ名前を付けられないことですが、それを回避する方法はたくさんあり、実際には表面的な制限です。

于 2012-09-25T09:27:09.683 に答える
1

パーツ クラスをクラス内で囲むだけDocumentです。

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

これを有効に使用できます:

Document myDoc;   // Type Document
Document::Header myHeader;
于 2012-09-25T09:27:23.960 に答える
0

ネストされたクラスをどの程度公開したいかは完全にはわかりませんが、それらが の一部である場合はDocument、おそらくネストされたクラスにする必要があります。コードの最初にあるあなたの例は、C++でこれを行う方法とまったく同じです。

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

私が見ることができる唯一の異議については、関連する実装ファイルにはクラス定義Document::Header全体を含める必要があるDocument ということですが、これは大きな問題ではないと思います。Document::Header本当に独立していない場合 は、これを要求するのが妥当と思われます。このソリューションに対する 2 番目の異議に関しては、オブジェクトをその部分から派生させたくありませDocument HeaderisA関係ではありません。

Headeret al を別々に使用することが理にかなっている場合、最善の解決策は、それらをDocumentクラスの外で定義し、よりわかりやすい名前を付ける (例: DocumentHeader) か、特別な名前空間でラップする (例: namespace DocumentParts) ことです。との関係によっては、in を使用して、 または のいずれかとして参照できるようにすることが Document理にかなって いる場合があります。typedefDocumentDocumentParts::HeaderDocument::Header

于 2012-09-25T09:52:59.360 に答える