2009-07-19 14 views
1

Il s'agit d'une question sur ce que définit une classe publique ou privée.classe privée/publique dans le problème d'espace de noms

À l'heure actuelle, j'ai différentes classes définies à l'intérieur d'un espace de noms et je veux seulement certains de ces classes pour être visible/utilisable pour le monde extérieur. Donc, par exemple, si les classes ci-dessous étaient les seules dans le programme, je voudrais que main.cpp soit seulement capable de voir/utiliser la classe MyPublic, pas la classe MyPrivate. Je pensais que définir la classe MyPrivate comme privé et la classe MyPublic comme public accomplirait cela, mais le code ci-dessous fonctionne et main.cpp est capable de déclarer un objet MyPrivate.

Est-il possible de faire cela en 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; 
} 
+0

C'est le "C++ géré" de dot net: ce n'est pas "C++". – ChrisW

+0

Utilisez-vous C++ ou C++/CLI? – Thanatos

+0

J'ai repensé la question, car dans le C++ non-géré, il n'y a pas de classe publique/privée. –

Répondre

3

privé/public dans cette situation aura une incidence sur la façon dont les classes sont visibles à l'extérieur un assemblage, si vous voulez créer une classe qui est "privée" dans le sens où elle ne peut être utilisée que par classe r, vous pouvez utiliser le mécanisme clas imbriqué, comme ceci:

 
namespace MyNamespace { 
    public ref class MyPublic { 
     private: 

      ref class MyPrivate { 
       public: 
       int x; 
      }; 

      MyPrivate^ p; 
    }; 
} 

// Edit: Vous pouvez par la section de façon encore lancer cette classe imbriquée dans public: et l'utiliser comme ceci:
MyNamespace::MyPublic::MyPrivate priv;

0

Votre en-tête public ne doit pas inclure d'en-tête privé. Forward déclare la classe privée et inclut l'en-tête uniquement dans MyPublic.cpp. Ou c'est ce que je dirais si vous utilisiez du C++ normal. Bastardized .Net dialect pourrait changer les choses.

0

Malheureusement, les modificateurs d'accès d'une classe n'affectent que la visibilité en dehors de l'assemblage que vous construisez. C++ ne prend pas en charge les modificateurs d'accès qui s'appliquent aux espaces de noms de la manière que vous décrivez.

Un idiome courant pour simuler ceci est de placer le code "privé" dans un espace de noms detail (par exemple le mettre dans MyNamespace::detail). Ceci est beaucoup utilisé par ex. les bibliothèques de boost. Par convention, le code dans un espace de noms détaillé ne doit être utilisé que par du code dans l'espace de noms englobant (donc MyNamespace::detail ne doit être utilisé que par code dans MyNamespace), bien que le compilateur ne le fasse pas pour vous.

1

Le mot-clé private signifie autre chose que vous ne le pensez. Je limite la visibilité de la classe ref au-delà de l'assemblage. Puisque votre méthode Main() est dans le même assembly, il n'a aucun problème à référencer le nom du type. Notez que le mot clé "internal" du langage C# signifie la même chose.

Je suppose que vous avez vraiment l'intention que ces classes soient dans un assembly séparé un jour. En tant que tel, l'utilisation privée est certainement assez bon. L'utilisation de classes privées imbriquées peut rendre une classe inaccessible au code dans le même assembly.

Questions connexes