2016-08-09 104 views
1

Ich weiß, dass, wenn kein Konstruktor für eine Klasse deklariert ist, der Compiler einen generiert. Nachdem jedoch das folgende (g ++ oder Klirren ++) Kompilieren und nm -C mit diesem Code zu tun - das ist ein nicht-POD Datenelement - ich das erzeugte Ctor tun sehen:Erstellter Konstruktor für POD- und Nicht-POD-Fälle

class X 
{ 
public: 
    void SetName(std::string name) {m_name = name;} 
private: 
    std::string m_name; 
}; 

int main() 
{ 
    X x1; 
    x1.SetName("jude"); 

    return 0; 
} 

Aber mit diesem Code - mit einem POD Datenelement - ich nicht:

class X 
{ 
public: 
    void SetNum(int num) {m_x = num;} 
private: 
    int m_x; 
}; 

int main() 
{ 
    X x1; 
    x1.SetNum(8); 

    return 0; 
} 

Ich dachte, dass ich in beiden Fällen einen generierten Konstruktor sehen würde. Entspricht dieses Verhalten dem Standard? Oder ist es etwas anderes, das hier vor sich geht?

Antwort

4

Im Falle von

class X 
{ 
public: 
    void SetName(std::string name) {m_name = name;} 
private: 
    std::string m_name; 
}; 

Ein Konstruktor muss als m_name Bedarf erzeugt werden standardmäßig gebaut werden.

Im Fall von

class X 
{ 
public: 
    void SetNum(int num) {m_x = num;} 
private: 
    int m_x; 
}; 

Standard m_x Konstruktion ist das gleiche wie nichts zu tun, als die Variable nicht initialisierten gelassen wird. Da das Generieren und Aufrufen des Konstruktors nicht dasselbe tut, was der Konstruktor tun würde, kann der Compiler es unter der "as-if" rule optimieren.

+0

Gibt es eine Compilation \ Linking Flag, die ich verwenden kann, um diese Optimierung zu deaktivieren? – HeyJude

+0

@HeyJude Ich bin mir nicht sicher. Das Ausschalten von Optimierungen kann helfen, aber das ist wirklich keine Lösung. Brauchen Sie den Konstruktor wirklich? Es ist ein Nicht-OP. – NathanOliver

+0

@HeyJude Sie können die Codes ohne main() kompilieren, indem Sie einfach .o Dateien erzeugen und diese überprüfen. – Walter

0

Die Ausgabe von nm -C ist nicht gebunden an die als-ob-Regel. Denken Sie daran, inline ist nur ein Hinweis auf den Compiler, und es kann jeden anderen Hinweis verwenden, der auch als passend erachtet wird - einschließlich der Komplexität einer Funktion. Offensichtlich variieren diese beiden Konstruktoren in ihrer Komplexität. In der Tat ist im POD-Fall der erzeugte ctor buchstäblich trivial, und es ist völlig vernünftig für einen Compiler, diesen zu inline zu schreiben.