1

これは、クラスをパブリックまたはプライベートとして定義する方法に関する質問です。

現在、名前空間内にさまざまなクラスが定義されており、それらのクラスの一部のみを外の世界に表示/使用できるようにしたいと考えています。

したがって、たとえば、以下のクラスがプログラム内の唯一のものである場合、main.cpp は MyPrivate クラスではなく、MyPublic クラスのみを表示/使用できるようにする必要があります。MyPrivate クラスを private として、MyPublic クラスを public として定義すればこれが達成できると思っていましたが、以下のコードは機能し、main.cpp は MyPrivate オブジェクトを宣言できます。

C++でこれを行うことは可能ですか?

MyPrivate.h:

namespace MyNamespace{

    // only classes inside of the MyNamespace should be able
    // to use this
    private ref class MyPrivate{
        ...
    };
}

MyPublic.h:

#include "MyPrivate.h"

namespace MyNamespace {

    // anyone can declare this
    public ref class MyPublic{
        ...
        private:
            MyNamespace::MyPrivate^ p;
        ...
    };
}

Main.cpp:

#include "MyPublic.h"

int main(){

    MyNamespace::MyPublic p_yes; // this is fine    
    MyNamespace::MyPrivate p_no; // don't want this to be possible

    return 0;
}
4

4 に答える 4

3

この状況でのプライベート/パブリックは、アセンブリの外部でクラスがどのように表示されるかに影響します。他のクラスでのみ使用できるという意味で「プライベート」なクラスを作成する場合は、ネストされたクラスメカニズムを使用できます。これ:

名前空間 MyNamespace {
    公開参照クラス MyPublic {
       プライベート:

           参照クラス MyPrivate {
               公衆:
               int x;
           };

           マイプライベート^ p;
    };
}

//編集: ちなみに、このネストされたクラスをpublic:セクションにスローして、次のように使用できます。
MyNamespace::MyPublic::MyPrivate priv;

于 2009-07-19T20:49:59.103 に答える
1

private キーワードは、あなたが思っている以上の意味を持っています。アセンブリを超えた ref クラスの可視性を制限します。Main() メソッドは同じアセンブリにあるため、型名の参照に問題はありません。C# 言語の "internal" キーワードは同じことを意味することに注意してください。

これらのクラスがいつか別のアセンブリになることを本当に意図していると思います。そのため、private を使用するだけで十分です。入れ子になったプライベート クラスを使用すると、同じアセンブリ内のコードからクラスにアクセスできなくなる可能性があります。

于 2009-07-19T21:04:35.020 に答える
0

パブリック ヘッダーにプライベート ヘッダーを含めないでください。プライベート クラスを前方宣言し、ヘッダーのみを MyPublic.cpp に含めます。または、通常の C++ を使用している場合は、そう言うでしょう。ろくでなしの .Net 方言は状況を変えるかもしれません。

于 2009-07-19T20:56:57.327 に答える
0

残念ながら、クラスのアクセス修飾子は、構築しているアセンブリの外部の可視性にのみ影響します。C++ は、あなたが説明している方法で名前空間に適用されるアクセス修飾子をサポートしていません。

これをシミュレートするための一般的なイディオムは、「プライベート」コードをdetail名前空間に入れることです (例: put it in MyNamespace::detail)。これは、boost ライブラリなどでよく使用されます。慣例により、detail 名前空間のコードは、囲んでいる名前空間のコードでMyNamespace::detailのみ使用する必要があります (したがって、 のコードでのみ使用する必要がありますMyNamespace)。ただし、コンパイラはこれを強制しません。

于 2009-07-19T20:58:21.147 に答える