2016-05-01 5 views
0

In Java können wir wie so ein neues Objekt auf ein Verfahren innerhalb seiner Parameter erstellen und weitergeben:Erstellen eines neuen Objekts und vorbei in Methodenparameter

wrapper.set_state(new Medium()); 

Was ist das Äquivalent dazu in C++? Ich nehme an, ich könnte das Objekt vorher erstellen und es dann übergeben, aber in der Lage zu sein, es in dem Parameter zu erstellen, würde sauberer erscheinen.

+0

Was Sie oben geschrieben haben, ist zufällig gültiger C++ - Code. –

+1

In C++ ist nichts mit 'wrapper.set_state (Medium());' verkehrt. –

+0

@SamVarshavchik Ahhhh, ok. Müsste ich das Objekt löschen? –

Antwort

-1

Es ist auf der Art des Parameters abhängig ist, sollten Sie Folgendes beachten:

  • Parameter Value: void set_state(Medium) bewegen initialisieren es mit einem temporären, dh set_state(Medium())
  • Rvalue-Reference-Parameter verwenden: void set_state(Medium&&), binden sie um auf ein neu konstruiertes temporäres zu verweisen, dh set_state(Medium()) zu verwenden (dies ist die gleiche Syntax wie der Wertparameter-Fall, aber die Semantik unterscheidet sich geringfügig)
  • Lvalue-Referenzparameter: void set_state(Medium&), übergeben Sie einen Verweis auf ein neu zugeordnetes o bject, dh set_state(*new Medium())
  • Pointer Parameter verwenden: void set_state(Medium*), gibt ihnen einen Zeiger auf ein neu zugewiesenen Objekt, also verwenden set_state(new Medium())

Das gleiche gilt, wenn der Parametertyp Jeden const oder volatatile Modifikatoren hat, und auch, wenn der Parameter mit einem Typ deklariert ist, dass ein nicht-ambigiouse Basistyp Medium


Hinweis ist: vorsichtig sein, wenn new verwendet wird, im Gegensatz zu Java, C++ erfordert keine automatische Garbage Sammlung, so wollen Sie sicherstellen, dass das Objekt gelöscht wird, wenn es nicht mehr benötigt wird und nicht zuvor. (die sicherste Sache wäre, nur nicht delete Ihre Objekte, aber dies wird nur Speicherverschwendung)

Ein weiterer Hinweis, wie C++ unterscheidet sich sehr von Java (in Semantik) Ich schlage vor, ein gutes Buch oder eine andere Ressource zu lesen die Sprache im Gegensatz dazu, Fragen über alles zu stellen, was du nicht verstehst, da du wahrscheinlich einige wichtige Unterschiede auf diese Weise verpassen wirst und katastrophale Folgen haben wirst.

+0

Bitte verwenden Sie '* new Medium()' nicht als Beispiel. Das ist fast garantiert, Speicher zu verlieren und höchstwahrscheinlich nicht angemessen. – user2079303

1

Was entspricht das in C++?

Es gibt mehrere ähnliche Möglichkeiten, die in Java angegebene Anweisung in C++ zu implementieren. Die exakt gleiche Syntax passiert tatsächlich, wenn die Funktion einen Zeiger erwartet. Ob es wünschenswert ist, an die Funktion zu übergeben, ein roher Zeiger auf ein manuell zugeordnetes Objekt, ist etwas, das Sie beachten müssen. Es ist wahrscheinlich nicht wünschenswert.

Der einfachste Weg, um ein neues Objekt in C++ zu erstellen, ist ein temporäres zu erstellen. Die analoge Syntax für eine temporäre erstellen und an eine Funktion wäre:

wrapper.set_state(Medium()); 

Da Java-Referenzen gezählt werden, würde die semantisch nächste Analogon (wahrscheinlich wohl), ein std::shared_ptr<Medium> passieren. Aber weil Sie in C++, anders als in Java, die Möglichkeit haben, Wert-Semantik zu verwenden, aber auf der anderen Seite keine Garbage-Collection haben, können Sie nicht davon ausgehen, dass Sie eigentlich dieselbe Semantik haben sollten.

0

Equivalent ja, aber vielleicht nicht dieselben Ergebnisse:

#include <iostream> 
#include <memory> // c++11 

class Helper { 
public: 
    Helper() { std::cout << "Helper says hi\n"; } 
    void Speak() { std::cout << "Helper says bark\n"; } 
    ~Helper() { std::cout << "Helper says bye\n"; } 
}; 

class Message { 
public: 
    Message (Helper* h, bool freeme = false) { 
     std::cout << "Message says hi..btw you have a memory leak\n"; 
     h->Speak(); 
     if (freeme) { 
      std::cout << "Message says nice one\n"; 
      delete h; 
     } 
    } 
    Message (std::unique_ptr<Helper> h) { 
     std::cout << "Message say hi\n"; 
     h->Speak(); 
    } 
    ~Message() { 
     std::cout << "Message says bye\n"; 
    } 
}; 

int main() 
{ 
    { Message msg1(new Helper); } // warning: leak 
    std::cout << "--- 1 ---\n"; 
    { Message msg2(std::unique_ptr<Helper>(new Helper));} 
    std::cout << "--- 2 ---\n"; 
    { Message msg3(new Helper); } // warning: leak 
    std::cout << "--- 3 ---\n"; 
    { Message msg3(new Helper, true); } 
    return 0; 
} 
3

In Java

wrapper.set_state(new Medium()); 

schafft eine neue Referenz gezählt, zB von Medium und leitet sie durch Bezugnahme auf Wrapper die set_state Funktion.

in C++ der obigen Code technisch gültig ist, würde in der Wrapper-Klasse set_state definiert werden als:

void set_state(Medium* medium); 

Aber was würden Sie tun, eine Nicht-Referenz gezählt Zeiger auf eine neue Instanz von Medium ist vorbei . Sie wären dafür verantwortlich, dass es später delete d ist. Wenn alle set_state dies tat, war:

void set_state(Medium* medium) 
{ 
    this->medium = medium; 
} 

Sie würden jedes Mal, wenn ein Speicherleck einführen einen zweiten Anruf gemacht SET_STATE. Wenn Sie in C++ einen solchen rohen Zeiger überschreiben, gibt es keine Referenzzählung. Wenn niemand mehr auf die Zuteilung zeigt, ist die Zuteilung verloren gegangen.

Sie könnten es vorziehen, ein Objekt als Verweis weitergeben müssen:

void set_state(const Medium& medium) 
{ 
    this->medium = medium; // copy 
} 

über aufgerufen:

Medium m; 
// populate m 
wrapper.set_state(m); 

// or 

wrapper.set_state(Medium()); 

oder Sie nach Wert übergeben können:

void set_state(Medium medium) 
{ 
    this->medium = medium; // copy 
} 

// invocation: 

Medium m; 
// populate m 
wrapper.set_state(m); // copy 

Obwohl dies ein Exemplar In einigen Fällen ist der Compiler in der Lage, eine der Kopien auszugeben (siehe http://ideone.com/gNICYt)

Wenn Sie unbedingt einen Zeiger verwenden müssen (mehrere Dinge verweisen genau auf die mittlere Instanz), sollten Sie die Verwendung von std::shared_ptr in Betracht ziehen, die eine Referenzzählung bietet.

#include <memory> 

struct Medium {}; 
class Wrapper { 
    std::shared_ptr<Medium> medium; 

public: 
    void set_state(std::shared_ptr<Medium> medium) { 
     this->medium = medium; // if we'd called it m_medium, or medium_ 
     // we could just have written 
     // m_medium = medium; or medium_ = medium; 
    } 
}; 

int main(void) { 
    Wrapper w; 
    w.set_state(std::make_shared<Medium>()); 

    return 0; 
} 
+0

@ user2079303 hinzugefügt, siehe bearbeitete Antwort. – kfsone

+0

@kfsone Werden nicht alle Objekte trotzdem als Referenz übergeben? Was genau würde die Verwendung von "Const" erreichen? Würde das Objekt irgendwann automatisch gelöscht, und wenn ja, wann? –

+0

@kfsone gute Zugabe. – user2079303