Heim > Backend-Entwicklung > C++ > Hauptteil

C++-Kompilierungsfehler: Vom flüchtigen Typ konvertierte Mitgliedsfunktion kann nicht aufgerufen werden. Wie gehe ich damit um?

PHPz
Freigeben: 2023-08-21 21:28:55
Original
934 Leute haben es durchsucht

C++ ist eine stark typisierte Sprache, die die Typkonvertierung von Variablen streng einschränkt. In einigen Fällen müssen wir jedoch möglicherweise eine Typkonvertierung für flüchtige Typobjekte durchführen. Insbesondere in der eingebetteten Entwicklung müssen wir häufig auf Hardwareregister zugreifen normalerweise flüchtiger Art. Da Objekte vom flüchtigen Typ jedoch eine besondere Semantik haben, erlegt der C++-Compiler ihnen einige besondere Einschränkungen auf, was zu der Fehlermeldung „Mitgliedsfunktionen, die aus flüchtigen Typen konvertiert werden können, können nicht aufgerufen werden“ führt. In diesem Artikel wird die Ursache dieses Fehlers erläutert und wie man damit umgeht.

Schauen wir uns zunächst die Semantik flüchtiger Typen an. In C++ besteht die Rolle des Schlüsselworts volatile darin, dem Compiler mitzuteilen, dass der Wert dieser Variablen außerhalb des Programms geändert werden kann, sodass der Compiler sie nicht optimieren kann und sicherstellen muss, dass ihr Wert bei jedem Zugriff erneut gelesen wird. Insbesondere weisen flüchtige Objekte die folgenden Eigenschaften auf:

  • Der Wert eines flüchtigen Objekts kann außerhalb des Programms geändert werden, z. B. durch Hardware-Interrupts, Multithreading usw.
  • Jedes Mal, wenn auf ein flüchtiges Objekt zugegriffen wird, muss sein Wert erneut gelesen werden und der zwischengespeicherte Wert im Register kann nicht direkt verwendet werden.
  • Der Zugriff auf flüchtige Objekte kann nicht neu angeordnet oder optimiert werden und muss in der Reihenfolge im Programm erfolgen.

Unter dieser Semantik können wir Objekte vom flüchtigen Typ zur Darstellung von Hardwareregistern verwenden. Es ist zu beachten, dass Objekte vom flüchtigen Typ nicht in und von Objekten vom nichtflüchtigen Typ konvertiert werden können, da dies ihre spezielle Semantik zerstört. Beispielsweise ist der folgende Code falsch:

int x = 0;
volatile int &y = x;   // 复制x的地址,但y是volatile类型

x = 1;  // OK,修改x的值
y = 2;  // OK,修改x的值,但要重新读取其值
int z = y;  // 错误,不能读取volatile对象的值
int &u = y;  // 错误,不能将volatile类型的引用转换为非volatile类型
Nach dem Login kopieren

Im obigen Code versuchen wir, die nichtflüchtige Variable x in die flüchtige Referenz y umzuwandeln, was falsch ist. Obwohl wir auf diese Weise den Wert von x über y ändern und seinen Wert bei jeder Änderung erneut lesen können, können wir den Wert von y nicht wie eine normale Ganzzahl lesen, da dies die Semantik des flüchtigen Typs verletzen würde.

Gehen wir noch einen Schritt weiter und betrachten wir eine komplexere Situation, nämlich den Aufruf einer Mitgliedsfunktion für ein Objekt vom flüchtigen Typ. Beispielsweise können wir eine Mitgliedsfunktion eines Objekts als flüchtigen Typ deklarieren, sodass die Sichtbarkeit seiner Mitgliedsvariablen beim Aufruf gewährleistet werden kann. Der C++-Compiler erlaubt jedoch keine Konvertierung von flüchtigen Typen in nichtflüchtige Typen, sodass der Kompilierungsfehler „Vom flüchtigen Typ konvertierte Mitgliedsfunktion kann nicht aufgerufen werden“ auftritt. Zum Beispiel:

class MyClass {
public:
    volatile int x;
    volatile void func() { x = x + 1; }
};

int main() {
    MyClass obj;
    obj.func();  // 错误,不能从volatile类型转换为非volatile类型
    return 0;
}
Nach dem Login kopieren

Im obigen Code definieren wir eine MyClass-Klasse, wobei x eine Ganzzahl vom flüchtigen Typ ist und func() eine Mitgliedsfunktion vom flüchtigen Typ ist, was bedeutet, dass eine automatische Inkrementierungsoperation für x ausgeführt wird. In der Funktion main() erstellen wir ein MyClass-Objekt obj und versuchen, seine Mitgliedsfunktion func() aufzurufen. Dies führt jedoch zu dem Kompilierungsfehler „Eine vom flüchtigen Typ konvertierte Mitgliedsfunktion kann nicht aufgerufen werden“. Dies liegt daran, dass Memberfunktionen in C++ als gewöhnliche Funktionen mit einem ausgeblendeten Zeigerparameter „this“ behandelt werden. Daher ist beim Aufrufen einer Memberfunktion die Konvertierung des Zeigers „this“ von einem nichtflüchtigen Typ in einen flüchtigen Typ nicht zulässig.

Wie sollen wir also mit diesem Kompilierungsfehler umgehen? Es gibt zwei Möglichkeiten, dieses Problem zu lösen. Die erste Methode besteht darin, die Parameter der Mitgliedsfunktion als flüchtige Typen zu deklarieren, damit der Compiler keinen Fehler meldet. Zum Beispiel:

class MyClass {
public:
    volatile int x;
    void func(volatile MyClass *thisptr) { thisptr->x = thisptr->x + 1; }
};

int main() {
    MyClass obj;
    obj.func(&obj);  // OK,将this指针转换为volatile类型
    return 0;
}
Nach dem Login kopieren

Im obigen Code deklarieren wir den Parameter thisptr der Funktion func() als MyClass-Zeiger vom flüchtigen Typ, sodass der Zeiger this beim Aufruf von einem nichtflüchtigen Typ in a konvertiert werden kann flüchtiger Typ. Obwohl dieser Ansatz das Problem lösen kann, macht er den Code ausführlicher und wird nicht sehr häufig verwendet.

Die zweite Methode besteht darin, mithilfe der Typlöschungstechnologie den This-Zeiger der Mitgliedsfunktion in einen Void-Zeiger umzuwandeln, sodass die Einschränkungen des Compilers für flüchtige Typen umgangen werden können. Zum Beispiel:

class MyClass {
public:
    volatile int x;
    void func() {
        volatile void *vthis = static_cast<volatile void *>(this);
        volatile MyClass *vptr = static_cast<volatile MyClass *>(vthis);
        vptr->x = vptr->x + 1;
    }
};

int main() {
    MyClass obj;
    obj.func();  // OK,使用类型擦除将this指针转换为volatile类型
    return 0;
}
Nach dem Login kopieren

Im obigen Code verwenden wir static_cast, um diesen Zeiger zuerst in einen void-Zeiger und dann in einen flüchtigen MyClass-Zeiger umzuwandeln, sodass wir einen flüchtigen this-Zeiger erhalten können. Obwohl dieser Ansatz das Problem lösen kann, erfordert er Kenntnisse über die Verwendung von Typlöschtechniken und kann die Lesbarkeit und Wartbarkeit des Codes beeinträchtigen.

Zusammenfassend lässt sich sagen, dass der C++-Kompilierungsfehler „Mitgliedsfunktionen, die aus flüchtigen Typen konvertiert werden können, können nicht aufgerufen werden“ durch die besonderen Einschränkungen des Compilers für flüchtige Typen verursacht wird. Um diesen Kompilierungsfehler zu beheben, können wir die Parameter der Mitgliedsfunktion als flüchtige Typen deklarieren oder die Technologie zur Typlöschung verwenden, um den Zeiger this der Mitgliedsfunktion in einen ungültigen Zeiger umzuwandeln. Unabhängig davon, welche Methode verwendet wird, müssen Sie auf die Semantik flüchtiger Typen achten, um zu verhindern, dass flüchtige Objekte in nichtflüchtige Objekte und umgekehrt umgewandelt werden, was zu falschen Ergebnissen führen kann.

Das obige ist der detaillierte Inhalt vonC++-Kompilierungsfehler: Vom flüchtigen Typ konvertierte Mitgliedsfunktion kann nicht aufgerufen werden. Wie gehe ich damit um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!