2016-07-29 3 views
-1

ich ein Problem mit einer Leistung von 2 Klassen haben wie unten:Zeiger auf ein Objekt hat keinen beliebigen Wert (oder nicht bekommen Wert)

foo.h

public: 
    Foo(){} ; 
    Foo(string); 
    Foo(const Foo&); 
    string getFooName() const; 
    ~Foo(); 
private: 
    string foo; 

foo.cpp

Foo::Foo(string n):foo(n){ 
} 

Foo::Foo(const Foo &f):foo(f.foo){ 
} 

string Foo::getFooName() const{ 
    return foo; 
} 

Foo::~Foo(){ 
} 

und Klasse Bar:

bar.h

public: 
    Bar(); 
    Bar(string, Foo&); 
    Bar(const Bar&); 
    Foo& getFoo() const; 
    ~Bar(); 
private: 
    string bar; 
    Foo* foo; 
}; 

Bar.cpp

Bar::Bar(string b, Foo &f):bar(b), foo(new Foo()){ 
} 

Bar::Bar(const Bar &b):bar(b.bar), foo(new Foo(*b.foo)){ 
} 

Foo &Bar::getFoo() const{ 
return *foo; 
} 

Bar::~Bar() 
{ 
delete foo; 
} 

und in Haupt-Funktionen erzeugt, wenn ich diese verwenden cout<<"Test:"<<b->getFoo().getFooName(); wird es mir nur in der Ausgabe nur Test: statt Test:TestFoo.

Was ist falsch in meinem Code? (Gcc5.4.0, Cmake 3.5.1) tnx

und main.cpp

Foo* f; 
Bar* b; 
f=new Foo("TestFoo"); 
b=new Bar("TestBar",*f); 
cout<<"Test:"<<b->getFoo().getFooName(); // this line 
+1

Bar :: Bar (String b, Foo & f): bar (b), foo (neu Foo()) {'Ihr Konstruktor' foo' Argument wird ignoriert und eine neue leere 'Foo' Instanz wird immer erzeugt. – Ari0nhh

Antwort

4
Bar::Bar(string b, Foo &f):bar(b), foo(new Foo()){} 

Parameter f ist ungenutzt. Sie müssen es an den Foo Konstruktor übergeben.

Bar::Bar(string b, Foo &f):bar(b), foo(new Foo(f)){} 
1

Wenn Sie

b = new Bar("TestBar", *f); 

der folgende Konstruktor aufrufen heißt:

Bar::Bar(string b, Foo &f):bar(b), foo(new Foo()) 

Wie Sie sehen können, der zweite Parameter nicht verwendet wird, um das foo Mitglied zu initialisieren, sondern eine neue man erstellt stattdessen. Es ist nicht das gleiche Objekt, das Sie mit dem "TestFoo" initialisiert haben!

Also, wenn Sie drucken, wird "TestFoo" überhaupt nicht zurückgegeben.

1

Das Problem liegt in Bar.cpp:

Der erste Konstruktor für Bar ist

Bar::Bar(string b, Foo &f):bar(b), foo(new Foo()){ 
} 

Dieser weist den Compiler einen Zeiger auf ein neues Foo Objekt zu erstellen, in dem Bar Objekt zu speichern. Das neue Objekt Foo hat jedoch nichts mit dem Objekt Foo zu tun, das als Eingabe an den Konstruktor übergeben wurde.Der Konstruktor muss das Foo Objekt als Eingabe übergeben verwenden, so dass das neue Foo Objekt den gleichen Wert in der Membervariable hat foo:

Bar::Bar(string b, Foo &f):bar(b), foo(new Foo(f.foo)){ 
} 

Dann wird der Konstruktoraufruf

b=new Bar("TestBar",*f); 

in main.cpp wird ordnen Sie der Elementvariable foo einen Wert von "TestFoo" zu (während zuvor die Variable nicht initialisiert wurde).

Als Ergebnis sollte b->getFoo().getFooName() "TestFoo" wie gewünscht zurückgeben.

Verwandte Themen