3653 Stimmen

Was bedeutet das Schlüsselwort explicit?

Was bedeutet die explicit Schlüsselwort in C++ bedeuten?

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 Klasse BigInt mit einem Umwandlungsoperator in int und einen expliziten Umwandlungsoperator in std::string aus welchem Grund auch immer. Sie werden sagen können int i = myBigInt; aber Sie müssen explizit einen Cast durchführen (mit static_cast , vorzugsweise), um zu sagen std::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!

51voto

SankararaoMajji Punkte 459

El explicit Schlüsselwort macht aus einem Konvertierungskonstruktor einen Nicht-Konvertierungskonstruktor. Infolgedessen ist der Code weniger fehleranfällig.

2 Stimmen

Direkte Antwort, wenn Sie C++ kennen, wenn nicht, können Sie zu cjm's Antwort gehen...

38voto

Helixirr Punkte 863

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 .

18 Stimmen

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 .

2 Stimmen

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.

0 Stimmen

" Konstruktor, der explizit aufgerufen werden muss " nein

32voto

selfboot Punkte 1341

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
}

1 Stimmen

explicit operator bool() vs. if ist ein Sonderfall. Es gibt keine Möglichkeit, ihn mit benutzerdefinierten Funktionen zu reproduzieren. Bool , explicit operator Bool() und eine Funktion namens If .

24voto

fmuecke Punkte 8668

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 .

26 Stimmen

Dieser Beitrag stammt aus dem Jahr 2009. Heute deklariert man sie nicht mehr als privat, sondern sagt = delete .

9voto

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

  • ganzzahlige Ränge aufwärts (char zu int, float zu double);
  • Standardkonvertierungen (int nach double);
  • Zeiger von Objekten in die Basisklasse und in void* umwandeln;

CodeJaeger.com

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.

Powered by:

X