2011-01-17 3 views
1

in meinem C++ - Programm Ich habe mehrere Namespaces, die mehrere Zeiger mit identischen Namen enthalten. Ich möchte dann eine Funktion einen Namespace nach einem Parameter auswählen. I.e. etwas wie:Switch-Namespace von If-Bedingung

#include <iostream> 

namespace ns1{ 
double x[5]={1,2,3,4,5}; 
} 
namespace ns2{ 
double x[5]={6,7,8,9,10}; 
} 

int main(){ 
    int b=1; 
    if(b==1){ 
    using namespace ns1; 
    } 
    if(b==2){ 
    using namespace ns2; 
    } 
    std::cout << x[3] << std::endl; 
} 

Dies funktioniert jedoch nicht, da der Compiler beklagt, dass x in diesem Bereich nicht bekannt ist. Ich schätze das Problem ist, dass "using namespace ..." nur in der if-Anweisung gültig ist. Ich denke, dass es möglich sein sollte, Namespaces irgendwie zu wechseln, kann aber nicht herausfinden, wie ... Wissen Sie, wie Sie dies tun, ohne alle Variablen separat zu übertragen?

int main(){ 
    int b=1; 
    double *x; 
    if(b==1){ 
    x = ns1::x; 
    } 
    if(b==2){ 
    x = ns2::x; 
    } 
    std::cout << x[3] << std::endl; 
} 

Cheers, Pascal

Antwort

4

Namespaces sind eine Kompilierung-Funktion in C++, können Sie sie nicht manipulieren dynamisch in Laufzeit. Der beste Rat, den ich Ihnen geben könnte, ist einen anderen Ansatz zu versuchen - Namespaces sind wahrscheinlich nicht dazu gedacht, das zu tun, was Sie tun möchten. Also frage SO was du wirklich willst und du wirst wahrscheinlich eine gute Antwort bekommen, ohne das System zu verbiegen.

+0

ah, das wusste ich nicht. Also, eine Klasse definieren, die alles enthält, was in einem Arbeitsbereich enthalten ist, und das Casting wäre der eleganteste Weg? – pascal

+0

@ user575873: wahrscheinlich nicht, obwohl es funktionieren könnte. Das hört sich einfach nicht richtig an - warum brauchen Sie einen Namespace, wenn Sie ihn alle in eine Klasse einbinden wollen? Nochmals, ich schlage vor, Sie öffnen eine neue Frage und erklären genau, was Sie damit erreichen wollen. –

+0

Sie hatten Recht. Ich habe herausgefunden, dass Klassen besser zu meinem Problem passen. – pascal

1

Der Namensraum wird zur Kompilierungszeit verwendet. Der if-Zustand wird zur Laufzeit ausgeführt.

Sie können das Verhalten des Compilers zur Laufzeit nicht ändern.

0

die using namespace Direktiven im Grunde sagt der Compiler zu "versuchen, dies beim Auflösen von Symbolen zu verwenden", was zur Laufzeit nicht geschieht.

Ich habe kein Problem mit dem zweiten Ansatz sehen ....

+0

gut, wenn Sie viele Variablen in jedem Namespace haben, ist es ein bisschen mühsam zu schreiben ... – pascal

+0

Nun, Sie brauchen einen besseren Weg, um diese Variablen zu verwalten, vielleicht eine Struktur oder Klasse dann. – YeenFei

1

Ich verstehe nicht, warum Sie das nicht wollen:

double* dispatch(int b) 
{ 
    switch(b) 
    { 
     case 1: return ns1::x; 
     case 2: return ns2::x; 
     default: return 0; 
    } 
} 

int main() 
{ 
    int b=1; 
    std::cout << dispatch(b)[3] << std::endl; 
} 

Wenn diese wachsen wird, betrachten Verwenden von Klassen und Polymorphismen anstelle von Namespaces.

+0

In meinem realen Programm habe ich mehr als eine Variable pro Namensraum. In diesem Fall benötigen Sie auch mehr als eine Versandfunktion ... – pascal

+0

@pascal: Warum verwenden Sie dann keine Klassen und virtuellen Versand? –

+0

könnte ich natürlich das. Aber dann würden Sie wieder den ganzen Namespace in eine Klasse einschließen - und dann brauchen Sie den Namespace überhaupt nicht ... – pascal

0

Wie bereits erwähnt, wird es nicht funktionieren ... Ich würde vorschlagen, dass Sie Polymorphismus verwenden, wenn Sie viele Variablen, die Sie in Ihrer Container-Klasse setzen wollen das gewünschte Ergebnis zu erzielen:

// Header file 
class s 
{ 
    public: 
    double x[5]; 
} 

class s1: public s 
{ 
    public: 
    s1() { /* Assign x here */ };   
} 

class s2: public s 
{ 
    public: 
    s2() { /* Assign x here */ }; 
} 

// CPP file 
int main() 
{ 
    int b = 1; 
    s* sptr; 

    if (b == 1) 
    sptr = (s*)new s1(); 
    else 
    sptr = (s*)new s2(); 

    std::cout << sptr->x[3] << std::endl; 
    delete sptr; 
} 

Wenn Sie haben nur ein paar Variablen, die Sie Zeiger verwenden könnten.

int main() 
{ 
    int b = 1; 
    double *px; 
    double s1x = {1, 2, 3, 4, 5}; 
    double s2x = {6, 7, 8, 9, 10}; 

    if (b == 1) 
    px = &s1x; 
    else 
    px = &s2x; 

    std::cout << px[3] << std::endl; 
} 
+0

Frage nur: Warum müssen Sie Polymorphie verwenden? Können Sie nicht einfach eine Klasse s definieren und dann s1 und s2 als const s definieren? – pascal

+0

Sie müssen keinen Polymorphismus verwenden. Es hängt davon ab, wie komplex Ihre Implementierung ist. Wenn Sie viele allgemeine Variablen mit unterschiedlichen Werten haben, ist Polymorphismus eine gute Option, aber wenn Sie nur eine Variable (x) haben, gibt es viel einfachere Möglichkeiten, die Lösung zu implementieren (siehe CashCow's Antwort). – Keplerian

1

Im einfachsten Zustand haben Sie "statische" Daten, möchten aber entscheiden, welches Stück statischer Daten verwendet werden soll.

struct space 
{ 
    double x[5]; 
}; 

space space1 = space{ {1,2,3,4,5} }; 
space space2 = space{ {6,7,8,9,10} }; 

int main(int argc, char * argv[]) 
{ 
    space * s; 
    if(argc == 1) 
     s = &space1; 
    else 
     s = &space2; 
} 

In Wirklichkeit natürlich Ihre Räume werden mehr als nur ein Mitglied, und Sie werden sie in einer anderen Art und Weise zu füllen, aber es ist eine Möglichkeit, Sie, welche Instanz Sie verwenden wählen können.

Sie können Polymorphie verwenden, um Funktionen zu implementieren, aber es hängt viel davon ab, wofür Sie es brauchen.

+0

danke, das ist eigentlich, wie ich es am Ende getan habe! – pascal