частный / публичный класс в проблеме пространства имен - PullRequest
1 голос
/ 20 июля 2009

Это вопрос о том, что делает определение класса как публичного или частного.

В данный момент у меня есть различные классы, определенные внутри пространства имен, и я хочу, чтобы некоторые из этих классов были видимыми / использованными во внешнем мире.

Так, например, если бы нижеуказанные классы были единственными в программе, я бы хотел, чтобы main.cpp мог видеть / использовать только класс MyPublic, а не класс MyPrivate. Я думал, что определение класса MyPrivate как частного и класса MyPublic как открытого позволит это сделать, но приведенный ниже код работает, и 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 ]

3 голосов
/ 20 июля 2009

private / public в этой ситуации будет влиять на то, как классы видны вне сборки, если вы хотите создать «private» класс в том смысле, что он может использоваться только другим классом, вы можете использовать вложенные классы механизм, как это:

namespace MyNamespace {
    public ref class MyPublic {
       private:

           ref class MyPrivate {
               public:
               int x;
           };

           MyPrivate^ p;
    };
}

// Изменить: Кстати, вы все равно можете выбросить этот вложенный класс в секцию public: и использовать его так:
MyNamespace::MyPublic::MyPrivate priv;

1 голос
/ 20 июля 2009

Приватное ключевое слово означает нечто иное, чем вы думаете. Я ограничиваю видимость класса ref за пределами сборки. Поскольку ваш метод Main () находится в той же сборке, у него нет проблем со ссылкой на имя типа. Обратите внимание, что ключевое слово "internal" языка C # означает то же самое.

Я предполагаю, что вы действительно собираетесь когда-нибудь создать эти классы в отдельной сборке. Таким образом, использование private, безусловно, достаточно хорошо. Использование вложенных частных классов может сделать класс недоступным для кода в той же сборке.

0 голосов
/ 20 июля 2009

К сожалению, модификаторы доступа в классе влияют только на видимость вне сборки, которую вы строите. C ++ не поддерживает какие-либо модификаторы доступа, которые применяются к пространствам имен, как вы описываете.

Распространенной идиомой для симуляции этого является помещение "частного" кода в пространство имен detail (например, в MyNamespace::detail). Это часто используется, например, буст библиотеки. По соглашению код в детализированном пространстве имен должен использоваться только кодом во вложенном пространстве имен (поэтому MyNamespace::detail должен использоваться только кодом в MyNamespace), хотя компилятор не будет применять это для вас.

0 голосов
/ 20 июля 2009

Ваш публичный заголовок не должен включать частный заголовок. Форвард объявить закрытый класс и включить заголовок только в MyPublic.cpp. Или это то, что я бы сказал, если бы вы использовали обычный C ++. Ублюденный диалект .Net может изменить ситуацию.

...