2009-07-17 3 views
8

Ich habe einige seltsame Code gefunden ...Was passiert, wenn der Standardparameterwert in Code definiert ist, der an der Call-Site nicht sichtbar ist?

//in file ClassA.h: 
class ClassA { 
public: 
    void Enable(bool enable); 
}; 

//in file ClassA.cpp 
#include <ClassA.h> 
void ClassA::Enable(bool enable = true) 
{ 
    //implementation is irrelevant 
} 

//in Consumer.cpp 
#include <ClassA.h> 
.... 
ClassA classA; 
classA.Enable(true); 

Offensichtlich seit Consumer.cpp nur ClassA.h enthalten und nicht ClassA.cpp der Compiler in der Lage, um zu sehen, nicht, dass der Parameter einen Standardwert hat.

Wann hätte der deklarierte Standardwert von ClassA::Enable in der Signatur der Methodenimplementierung irgendwelche Auswirkungen? Würde dies nur passieren, wenn die Methode in Dateien aufgerufen wird, die ClassA.cpp enthalten?

Antwort

11

Standardwerte sind nur eine Kompilierzeit Sache. Es gibt keine Standardwerte in kompiliertem Code (keine Metadaten oder ähnliche Dinge). Es ist im Grunde ein Compiler-Ersatz für "Wenn Sie nichts schreiben, werde ich das für Sie angeben." Wenn also der Compiler den Standardwert nicht sehen kann, nimmt er an, dass es keinen gibt.

Demo:

// test.h 
class Test { public: int testing(int input); }; 

// main.cpp 
#include <iostream> 
// removing the default value here will cause an error in the call in `main`: 
class Test { public: int testing(int input = 42); }; 
int f(); 
int main() { 
    Test t; 
    std::cout << t.testing() // 42 
      << " " << f() // 1000 
      << std::endl; 
    return 0; 
} 

// test.cpp 
#include "test.h" 
int Test::testing(int input = 1000) { return input; } 
int f() { Test t; return t.testing(); } 

Test:

g++ main.cpp test.cpp 
./a.out 
1

Setzen Sie den Standardwert in die Deklaration, nicht die Definition.

class ClassA { 
public: 
    void Enable(bool enable = true); 
}; 
+0

Wer hat das markiert? Wenn Sie mich abschreiben, sagen Sie mir, warum ich es wenigstens beheben kann. –

+1

Eigentlich war ich es, der dies niederschrieb und der Grund war, dass der OP offensichtlich weiß, dass der richtige Weg darin besteht, dies in die Deklaration und nicht in die Definition zu schreiben. Der OP hat sich gefragt, was die Auswirkungen sind, wenn man so etwas in die Definition einbezieht, und Sie haben geantwortet, ohne die Frage gründlich zu lesen. Und ja, Entschuldigung dafür, dass ich Ihnen den Grund nicht erklärt habe. Ich hätte das tun sollen. – Aamir

+0

Das OP hat nicht erwähnt, dass es in die Erklärung aufgenommen wurde, also schlug ich eine Lösung für das Sichtbarkeitsproblem vor, die er erwähnt hat. –

1

Wäre dies nur dann geschehen, wenn die Methode aus Dateien aufgerufen wird, die die ClassA.cpp enthalten?

Das stimmt. Beachten Sie jedoch, dass dies mit ziemlicher Sicherheit zu mehreren Definitionsfehlern führt. Daher ist der Standardwert erst ab dem Definitionspunkt in ClassA.cpp verfügbar.

+0

Es ist kein Fehler. Es werden nur Fehler erzeugt, wenn beide Definitionen Standardwerte liefern. –

+0

Die eigentlichen Funktionen führen zu Mehrfachdefinitionsfehlern, wenn die Datei mehrfach eingeschlossen ist. Darauf bezog ich mich. –

3

Lassen Sie mich zuerst zugeben, dass dies das erste Mal ist, dass ich diese Art von Code gesehen habe. Setzen Sie einen Standardwert in Header-Datei IS die normale Praxis, aber das ist nicht.

Meine Vermutung ist, dass dieser Standardwert nur aus Code in der gleichen Datei verwendet werden kann und der Programmierer, der dies schrieb, wollte es in eine Art Leichtigkeit beim Aufruf der Funktion, aber er wollte nicht stören Sie die Schnittstelle (die Header-Datei) für die Außenwelt sichtbar.