Was bedeutet die explicit
Schlüsselwort in C++ bedeuten?
Direkte Antwort, wenn Sie C++ kennen, wenn nicht, können Sie zu cjm's Antwort gehen...
Was bedeutet die explicit
Schlüsselwort in C++ bedeuten?
El explicit
-Schlüsselwort kann verwendet werden, um den Aufruf eines Konstruktors zu erzwingen ausdrücklich .
class C {
public:
explicit C() =default;
};
int main() {
C c;
return 0;
}
el explicit
-Schlüsselwort vor dem Konstruktor C()
teilt dem Compiler mit, dass nur explizite Aufrufe dieses Konstruktors erlaubt sind.
El explicit
-Schlüsselwort kann auch in benutzerdefinierten Typ-Cast-Operatoren verwendet werden:
class C{
public:
explicit inline operator bool() const {
return true;
}
};
int main() {
C c;
bool b = static_cast<bool>(c);
return 0;
}
Hier, explicit
-Schlüsselwort erzwingt, dass nur explizite Würfe gültig sind, also bool b = c;
wäre in diesem Fall ein ungültiger Wurf. In Situationen wie diesen explicit
-Schlüsselwort kann dem Programmierer helfen, implizite, unbeabsichtigte Würfe zu vermeiden. Diese Verwendung ist standardisiert worden in C++11 .
C c();
im ersten Beispiel bedeutet nicht das, was Sie denken: Es ist die Deklaration einer Funktion namens c
die keine Parameter benötigt und eine Instanz von C
.
explicit operator bool()
ist auch die C++11-Version von safe bool, und kann implizit in Bedingungsprüfungen verwendet werden (und nur bei den Zustandsprüfungen, soweit ich weiß). In Ihrem zweiten Beispiel wäre diese Zeile auch gültig in main()
: if (c) { std::cout << "'c' is valid." << std:: endl; }
. Abgesehen davon kann sie jedoch nicht ohne ausdrücklichen Guss verwendet werden.
Cpp Referenz ist immer hilfreich!!! Details zum expliziten Spezifizierer finden Sie unter aquí . Möglicherweise müssen Sie sich Folgendes ansehen implizite Konvertierungen y Kopier-Initialisierung auch.
Schneller Blick
Der explizite Spezifizierer gibt an, dass ein Konstruktor oder eine Konvertierungsfunktion (seit C++11) keine impliziten Konvertierungen oder Kopierinitialisierungen zulässt.
Beispiel wie folgt:
struct A
{
A(int) { } // converting constructor
A(int, int) { } // converting constructor (C++11)
operator bool() const { return true; }
};
struct B
{
explicit B(int) { }
explicit B(int, int) { }
explicit operator bool() const { return true; }
};
int main()
{
A a1 = 1; // OK: copy-initialization selects A::A(int)
A a2(2); // OK: direct-initialization selects A::A(int)
A a3 {4, 5}; // OK: direct-list-initialization selects A::A(int, int)
A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
A a5 = (A)1; // OK: explicit cast performs static_cast
if (a1) cout << "true" << endl; // OK: A::operator bool()
bool na1 = a1; // OK: copy-initialization selects A::operator bool()
bool na2 = static_cast<bool>(a1); // OK: static_cast performs direct-initialization
// B b1 = 1; // error: copy-initialization does not consider B::B(int)
B b2(2); // OK: direct-initialization selects B::B(int)
B b3 {4, 5}; // OK: direct-list-initialization selects B::B(int, int)
// B b4 = {4, 5}; // error: copy-list-initialization does not consider B::B(int,int)
B b5 = (B)1; // OK: explicit cast performs static_cast
if (b5) cout << "true" << endl; // OK: B::operator bool()
// bool nb1 = b2; // error: copy-initialization does not consider B::operator bool()
bool nb2 = static_cast<bool>(b2); // OK: static_cast performs direct-initialization
}
Es ist immer eine gute Programmierpraxis, Ihre Ein-Argument-Konstruktoren (einschließlich derjenigen mit Standardwerten für arg2
, arg3
,...) wie bereits erwähnt. Wie immer bei C++: Wenn Sie es nicht tun, werden Sie sich wünschen, Sie hätten es getan...
Eine weitere gute Praxis für Klassen ist es, die Konstruktion und Zuweisung von Kopien privat zu machen (d.h. zu deaktivieren), es sei denn, Sie müssen sie wirklich implementieren. Dadurch wird vermieden, dass bei der Verwendung der Methoden, die C++ standardmäßig für Sie erstellt, eventuelle Kopien von Zeigern entstehen. Eine andere Möglichkeit, dies zu tun, ist die Ableitung von boost::noncopyable
.
Die Konstrukteure fügen eine implizite Konvertierung hinzu. Um diese implizite Umwandlung zu unterdrücken, ist es erforderlich, einen Konstruktor mit einem expliziten Parameter zu deklarieren.
In C++11 können Sie auch einen "Operatortyp()" mit einem solchen Schlüsselwort angeben http://en.cppreference.com/w/cpp/language/explicit Mit einer solchen Spezifikation können Sie Operator in Form von expliziten Konvertierungen und direkter Initialisierung von Objekten verwenden.
P.S. Bei der Verwendung von Transformationen, die BY USER (über Konstruktoren und Typkonvertierungsoperatoren) definiert wurden, darf nur eine Ebene von impliziten Konvertierungen verwendet werden. Aber Sie können diese Konvertierungen mit anderen Sprachkonvertierungen kombinieren
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
228 Stimmen
Ich möchte nur jeden, der neu hinzukommt, darauf hinweisen, dass seit C++11,
explicit
kann nicht nur auf Konstruktoren angewendet werden. Es gilt jetzt auch für Konvertierungsoperatoren. Angenommen, Sie haben eine KlasseBigInt
mit einem Umwandlungsoperator inint
und einen expliziten Umwandlungsoperator instd::string
aus welchem Grund auch immer. Sie werden sagen könnenint i = myBigInt;
aber Sie müssen explizit einen Cast durchführen (mitstatic_cast
, vorzugsweise), um zu sagenstd::string s = myBigInt;
.2 Stimmen
Kann man sich nicht auch explizit auf den Auftrag beziehen? (d.h..
int x(5);
)0 Stimmen
@chris Die Idee einer expliziten impliziten Umwandlung ist absurd. Lassen Sie die Finger davon!
4 Stimmen
@curiousguy, Es gibt keine explizite implizite Konvertierung.
0 Stimmen
@chris Es gibt ein explizites Schlüsselwort, das bei der Deklaration einer impliziten Konvertierung verwendet werden kann.
2 Stimmen
@curiousguy, Es ist nicht per se eine implizite Umwandlung. Das Einfügen von
explicit
deklariert dort eine explizite Konvertierung in einen Typ. Keine Selbstverständlichkeit in dem Prozess beteiligt.0 Stimmen
@chris Explizite Umwandlung ist ein schlecht definierter Begriff.
0 Stimmen
@curiousguy: Wie meinen Sie das? Alle Konvertierungen sollten implizit sein? Um alle Arten von stillschweigend angewandten, lustigen Fehlkonvertierungen aufgrund von zufälligen Mehrdeutigkeiten loszulassen? (Siehe z.B. den Abschnitt "Das sichere bool-Problem" unter diese Seite C++ref. o open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2333.html für (viel) mehr Details darüber, warum "Explizite Konvertierung ist ein schlecht definiertes Konzept." eine schlecht durchdachte Aussage ist).
0 Stimmen
@Sz. Ich meine, dass explizite Konvertierung keine Sache ist; es ist ein Müllkonzept. Auch das "safe bool" ist ein lächerlicher "Beweis" für die Nützlichkeit der Idee des "expliziten Operators", da es nicht einmal eine Anwendung dieser Idee ist, sondern ein anderer Satz von Regeln, was bedeutet die einzige praktische Verwendung von "explicit operator" in der SL ist ad hoc und nicht auf UDT anwendbar .
0 Stimmen
@chris meinten Sie so:
std::string s = static_cast<std::string>(myBigInt)
? Wenn möglich, könnten Sie bitte Ihren ersten Kommentar näher erläutern? Vielen Dank im Voraus!2 Stimmen
@Milan, Ja, das ist genau das Richtige. Wenn Sie mehr Informationen suchen, diese Antwort schreibt es förmlicher aus. Bitte beachten Sie, dass
bool
ist in dieser Hinsicht besonders . Diese Antworten und die Suche nach "expliziten Konvertierungsoperatoren" werden Sie zu weiteren Beiträgen über diese Funktion führen und sind besser geeignet als eine Kommentar-Kette.