2017-10-24 2 views
2

Ich erhalte einen Fehler beim Versuch, mein C++ - Projekt zu erstellen.Kollision mit eingebauten Funktionen benennen?

Ich versuche ein Cross-Plattform-Projekt mit Sockets zu erstellen. Unter Windows muss ich closesocket aufrufen, wenn ein Socket geschlossen ist, und auf Linux, ich rufe nur schließen.

Also, eine plattformübergreifende Lösung zu machen, ich folgendes in meiner Basisklasse definiert:

#define closesocket close 

In meiner Klasse Code, ich habe dann:

class TCPClient { 
    void TCPClient::close() 
    { 
     closesocket(m_socket); 
    } 
} 

Allerdings habe ich jetzt erhalten die folgende Fehlermeldung, wenn ich zu bauen versuchen:

projects/cpp_sockets/src/project/tcp_client.cpp: In member function ‘void TCPClient::close()’:                               
/home/optonox/Documents/projects/cpp_sockets/src/project/tcp_client.cpp:44:22: error: no matching function for call to                               
‘TCPClient::close(SOCKET&)’                                                     
    closesocket(m_socket); 


       ^                                                     /home/optonox/Documents/projects/cpp_sockets/src/project/tcp_client.cpp:42:6: note: candidate: void TCPClient::close()                               
void TCPClient::close()                                                      
     ^~~~~~~~~                                                        
/home/optonox/Documents/projects/cpp_sockets/src/project/tcp_client.cpp:42:6: note: candidate expects 0 arguments, 1                               
provided                                                          
src/project/CMakeFiles/cpp_sockets.dir/build.make:110: recipe for target 'src/project/CMakeFiles/cpp_sockets.dir/tcp_c 

ich würde vermuten, was passiert ist, dass closesocket ist typedef d als close so versucht es, die TCPclient Mitgliedsfunktion aufzurufen?

A. Ist das was passiert? und B. Wie würde ich das verhindern?

Das Projekt kompiliert in Ordnung, wenn ich diesen Aufruf an auskommentieren.

Antwort

5

Sie haben zwei Probleme.

Die erste ist, wie der Präprozessor funktioniert, es ersetzt Makroaufrufe, bevor der tatsächliche C++ - Parser den Code sieht. Das heißt, mit

#define closesocket close 

und

void TCPClient::close() 
{ 
    closesocket(m_socket); 
} 

was der C++ Parser sieht, ist

void TCPClient::close() 
{ 
    close(m_socket); 
} 

Das heißt, ein Versuch, rufen TCPClient::closerekursiv aber vorbei ein Argument der Funktion doesn‘ t nehmen.

Die Lösung für dieses erste Problem ist es, die Verwendung von Makros so viel wie möglich zu vermeiden, und stattdessen conditional compilation in der TCPClient::close Funktion direkt.

Das zweite Problem ist das Scoping und ist der Grund für den scheinbar rekursiven Aufruf.Sie müssen den Compiler sagen, dass Sie die globale close Funktion nutzen möchten, der den Anwendungsbereich-Operator :: wie in

::close(m_socket); 
+0

Fantastisch. Kristallklare Antwort. – Startec

+0

Ich hätte eine Wrapper-Funktion definiert, anstatt ein Makro '# define' zu ​​verwenden:' int closesocket (int fd) {return :: close (fd); } '. –

+0

@RemyLebeau, das die Plattformunterschiede, die das Makro tat, nicht ansprechen würde. – Startec

0
#ifdef _WIN32 ... 
    #define CLOSESOCKET closesocket 
#elif __linux__ ... 
    #define CLOSESOCKET close 
#endif 

class TCPClient { 
    .... m_socket 

    void close() 
    { 
     CLOSESOCKET(m_socket); 
    } 
}; 

Problem 1 erfolgt über: nach Klammer der Klasse Sie Semikolon brauchen

Problem 2: Sie Funktion mit Rahmen wie folgt erklären -> TCPClient :: close()

so wird Ihre Funktion des Oszilloskops TCPClient sein :: TCPClient :: close()

aber TCPClient Klasse nicht enthalten TCPClient Umfang

Problem 3: wenn Sie Cross-Plattform möchten, können Sie os mit vordefinierten überprüfen Compiler os Makro

https://sourceforge.net/p/predef/wiki/OperatingSystems/

Verwandte Themen