Domanda

Io vengo da una Java sfondo, dove i pacchetti vengono utilizzati, non gli spazi dei nomi.Io sono abituato a mettere le classi che funzionano insieme per formare un oggetto completo in pacchetti, per poi riutilizzarli in seguito da quel pacchetto.Ma ora sto lavorando in C++.

Come si fa a utilizzare gli spazi dei nomi in C++?Si fa a creare un unico spazio dei nomi per l'intera applicazione, o si fa a creare spazi per i componenti principali?Se è così, come si fa a creare oggetti da classi in altri spazi dei nomi?

È stato utile?

Soluzione

Gli spazi dei nomi sono pacchetti essenzialmente.Essi possono essere utilizzati come questo:

namespace MyNamespace
{
  class MyClass
  {
  };
}

Poi nel codice:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();

Speranza che aiuta.

O, se si desidera utilizzare sempre uno specifico spazio dei nomi, è possibile fare questo:

using namespace MyNamespace;

MyClass* pClass = new MyClass();

Edit: In seguito a ciò che bernhardrusch ha detto, io tendo a non usare il "using namespace x" la sintassi a tutti, io di solito esplicitamente specificare lo spazio dei nomi quando si crea un'istanza miei oggetti (es.il primo esempio che ho mostrato).

E come hai chiesto di seguito, si possono utilizzare tutti gli spazi dei nomi, come ti piace.

Altri suggerimenti

Per evitare di dire tutto ciò che Mark Ingram già detto un po ' di suggerimento per l'utilizzo di spazi dei nomi:

Evitare il "using namespace" direttiva nel file di intestazione - questo apre lo spazio per tutte le parti del programma che consente di importare questo file di intestazione.In attuazione di file (*.cpp) è, normalmente, non un grosso problema anche se io preferisco usare il "using namespace" direttiva sul livello di funzione.

Credo che gli spazi dei nomi sono per lo più utilizzati per evitare i conflitti di denominazione - non necessariamente organizzare il tuo codice struttura.Mi piacerebbe organizzare dei programmi C++ soprattutto con file di intestazione / la struttura del file.

A volte gli spazi dei nomi sono utilizzati in grandi progetti in C++ per nascondere i dettagli di implementazione.

Nota aggiuntiva per l'utilizzo di direttiva:Alcune persone preferiscono usare "uso" solo per i singoli elementi:

using std::cout;  
using std::endl;

Vincent Robert è proprio nel suo commento Come si fa a utilizzare correttamente gli spazi dei nomi in C++?.

Using namespace

Gli spazi dei nomi sono utilizzati almeno per evitare la collisione dei nomi.In Java, questo è imposto dal "org.dominio" idioma (perché si suppone che uno non usare nient'altro che la sua/il suo proprio nome di dominio).

In C++, si potrebbe dare uno spazio dei nomi a tutto il codice nel modulo.Per esempio, per un modulo MyModule.dll si potrebbe dare il suo codice lo spazio dei nomi Miomodulo.Mi è capitato di vedere altrove qualcuno che utilizza MyCompany::Progetto::Miomodulo.Credo che questa sia un'esagerazione, ma tutto sommato, mi sembra corretto per me.

L'utilizzo di "risorse"

Utilizzando deve essere utilizzato con grande cautela perché effettivamente l'importazione di uno (o tutti) i simboli di un namespace nel tuo spazio corrente.

Questo è di male a farlo in un file di intestazione perché l'intestazione ad inquinare ogni fonte, come è (mi ricorda le macro...), e anche in un file di origine, un cattivo stile al di fuori di un ambito funzione perché importa in ambito globale i simboli che lo spazio dei nomi.

Il modo più sicuro per l'uso "con" l'importazione di selezionare i simboli:

void doSomething()
{
   using std::string ; // string is now "imported", at least,
                       // until the end of the function
   string a("Hello World!") ;
   std::cout << a << std::endl ;
}

void doSomethingElse()
{
   using namespace std ; // everything from std is now "imported", at least,
                       // until the end of the function
   string a("Hello World!") ;
   cout << a << endl ;
}

Vedrete un sacco di "using namespace std ;" il tutorial o codici di esempio.Il motivo è quello di ridurre il numero di simboli per rendere la lettura più facile, non perché è una buona idea.

"using namespace std ;" è scoraggiato da Scott Meyers (non mi ricordo esattamente in quale libro, ma sono in grado di trovare, se necessario).

Spazio Dei Nomi Composizione

Gli spazi dei nomi sono più pacchetti.Un altro esempio può essere trovato nel Bjarne Stroustrup "The C++ Programming Language".

In "Edizione Speciale", a 8.2.8 Spazio Dei Nomi Composizione, egli viene descritto come è possibile unire i due spazi dei nomi AAA e BBB in un'altra chiamata CCC.Così CCC diventa un alias per entrambe le AAA e BBB:

namespace AAA
{
   void doSomething() ;
}

namespace BBB
{
   void doSomethingElse() ;
}

namespace CCC
{
   using namespace AAA ;
   using namespace BBB ;
}

void doSomethingAgain()
{
   CCC::doSomething() ;
   CCC::doSomethingElse() ;
}

Si potrebbe anche importare, selezionare simboli di spazi dei nomi diversi, per costruire il proprio spazio dei nomi personalizzato interfaccia.Devo ancora trovare un uso pratico di questo, ma in teoria, è cool.

Non ho visto alcuna menzione di esso in altre risposte, così qui sono i miei 2 centesimi Canadesi:

Sul "using namespace" argomento, un utile economico è lo spazio dei nomi di alias, che consente di "rinominare" uno spazio dei nomi, di solito per dare un nome più breve.Per esempio, invece di:

Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::TheClassName foo;
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::AnotherClassName bar;

si può scrivere:

namespace Shorter = Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally;
Shorter::TheClassName foo;
Shorter::AnotherClassName bar;

Non ascoltare la gente dicendo che gli spazi dei nomi sono solo nome di cat.

Essi sono importanti perché essi sono considerati dal compilatore per applicare i principi dell'interfaccia.Fondamentalmente, ciò può essere spiegato con un esempio:

namespace ns {

class A
{
};

void print(A a)
{
}

}

Se si desidera stampare Un oggetto, il codice dovrebbe essere questo:

ns::A a;
print(a);

Si noti che non si parla esplicitamente lo spazio dei nomi quando si chiama la funzione.Questa è l'interfaccia principio:C++ consideriamo una funzione di prendere un tipo come argomento come parte dell'interfaccia di quel tipo, quindi non c'è bisogno di specificare lo spazio dei nomi perché il parametro già implicita dello spazio dei nomi.

Ora, perché questo principio è importante?Immaginare che la classe di Un autore non fornisce una funzione print() per questa classe.Sarà necessario fornire uno voi stessi.Come voi sono un buon programmatore, è possibile definire questa funzione nel tuo spazio dei nomi, o forse nello spazio dei nomi globale.

namespace ns {

class A
{
};

}

void print(A a)
{
}

E il tuo codice può iniziare a chiamare la stampa(a) funzione di dove si vuole.Ora immaginate che, anni dopo, l'autore decide di fornire una funzione print (), migliore della tua, perché conosce i meccanismi interni della classe e può fare una versione migliore del tuo.

E poi C++ autori hanno deciso che la sua versione della funzione print() dovrebbe essere utilizzato al posto di quello fornito in un altro spazio dei nomi, a rispettare i principi dell'interfaccia.E che questo "upgrade" della funzione print() dovrebbe essere il più semplice possibile, il che significa che non dovrai cambiare ogni chiamata alla funzione print ().Ecco perché "le funzioni di interfaccia" (funzione nello stesso spazio dei nomi di una classe) può essere chiamato senza specificare lo spazio dei nomi in C++.

E perché si dovrebbe considerare un C++ spazio dei nomi come "interfaccia" quando si utilizza uno e tenere a mente i principi dell'interfaccia.

Se si desidera una migliore spiegazione di questo comportamento, è possibile fare riferimento al libro Exceptional C++ da Herb Sutter

Grandi progetti in C++ ho visto poco usato più di uno spazio dei nomi (ad es.libreria boost).

In realtà boost utilizza tonnellate di spazi dei nomi, in genere ogni parte del boost ha il proprio spazio dei nomi per il funzionamento interno e quindi può mettere solo l'interfaccia pubblica di livello superiore dello spazio dei nomi boost.

Personalmente, penso che la più grande base di codice diventa, il più importante spazi dei nomi diventare, anche all'interno di una singola applicazione (o libreria).Al lavoro abbiamo messo ogni modulo della nostra applicazione nel proprio spazio dei nomi.

Un altro uso (no pun intended) di spazi dei nomi che io uso un sacco è l'anonimo spazio dei nomi:

namespace {
  const int CONSTANT = 42;
}

Questo è fondamentalmente lo stesso come:

static const int CONSTANT = 42;

Utilizzando un anonimo spazio dei nomi (anziché statico) è tuttavia il modo consigliato per codice e dati per essere visibili solo all'interno dell'attuale unità di compilazione in C++.

Inoltre, si noti che è possibile aggiungere a uno spazio dei nomi.Questo è più chiaro con un esempio, quello che voglio dire è che si può avere:

namespace MyNamespace
{
    double square(double x) { return x * x; }
}

in un file square.h, e

namespace MyNamespace
{
    double cube(double x) { return x * x * x; }
}

in un file cube.h.Questo definisce un unico spazio dei nomi MyNamespace (che è, è possibile definire un unico spazio dei nomi in più file).

In Java:

package somepackage;
class SomeClass {}

In C++:

namespace somenamespace {
    class SomeClass {}
}

E il loro utilizzo, Java:

import somepackage;

E C++:

using namespace somenamespace;

Inoltre, i nomi sono "somepackge.SomeClass" per Java e "somenamespace::SomeClass" per C++.Utilizzando tali convenzioni, si può organizzare come si è abituati a in Java, inclusa la realizzazione di corrispondenza dei nomi delle cartelle per gli spazi dei nomi.Cartella->pacchetto e file->classe di requisiti non ci sono, però, così è possibile assegnare un nome alle cartelle e classi indipendentemente off pacchetti e spazi dei nomi.

Si possono anche contenere "using namespace ..." all'interno di una funzione, per esempio:

void test(const std::string& s) {
    using namespace std;
    cout << s;
}

@marius

Sì, è possibile utilizzare diversi spazi dei nomi a un tempo, per esempio:

using namespace boost;   
using namespace std;  

shared_ptr<int> p(new int(1));   // shared_ptr belongs to boost   
cout << "cout belongs to std::" << endl;   // cout and endl are in std

[Feb.2014 -- (Ha davvero passato così tanto tempo?):Questo particolare esempio è ora ambigua, come Joey punti di seguito.Boost e std::ora ciascuno di un shared_ptr.]

In generale, ho creato uno spazio dei nomi per un corpo di codice se credo che ci potrebbe essere la funzione o il nome del tipo di conflitti con altre biblioteche.Essa contribuisce anche a brand codice, ala boost:: .

Io preferisco usare un alto livello di spazio per l'applicazione e sub spazi dei nomi per i componenti.

Il modo in cui è possibile utilizzare le classi di altri namespace è sorprendentemente molto simile al modo in java.È possibile utilizzare "l'uso dello spazio dei nomi" che è simile ad un "PACCHETTO di importazione" dichiarazione", ad es.utilizzare std.O si specifica il pacchetto come prefisso della classe separata con "::", ad es.std::string.Questo è simile a java.lang.String" in Java.

Nota che uno spazio dei nomi in C++ è davvero solo un nome di spazio.Essi non forniscono alcuna di incapsulamento di pacchetti di fare in Java, quindi probabilmente non li uso molto.

Ho usato il C++ spazi dei nomi allo stesso modo fare in C#, Perl, etc.È solo una semantica separazione di simboli tra la libreria standard di roba, a terzi, cose e il mio codice.Vorrei porre la mia app in uno spazio dei nomi, una libreria riutilizzabile componente in un altro spazio dei nomi per la separazione.

Un'altra differenza tra java e C++, è che in C++, la gerarchia dello spazio dei nomi non ha bisogno di mach il layout del filesystem.Quindi tendo a mettere un'intera libreria riutilizzabile in un unico spazio dei nomi, e sottosistemi all'interno della libreria in sottodirectory:

#include "lib/module1.h"
#include "lib/module2.h"

lib::class1 *v = new lib::class1();

Vorrei solo mettere i sottosistemi in spazi dei nomi annidati se c'era una possibilità di un conflitto di nomi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top