c++ visual-studio-2010 oop boost include

c++ - Ya se definió en.obj-sin inclusiones dobles



visual-studio-2010 oop (3)

Este no es un error del compilador : el error proviene del enlazador . Después de la compilación, el enlazador fusionará los archivos de objetos resultantes de la compilación de cada una de sus unidades de traducción (archivos .cpp ).

El vinculador descubre que tiene el mismo símbolo definido varias veces en diferentes unidades de traducción, y se queja de ello (es una violación de la Regla de una sola definición).

La razón es sin duda client.cpp que main.cpp incluye client.cpp , y ambos archivos son procesados ​​individualmente por el compilador para producir dos archivos de objeto separados. Por lo tanto, todos los símbolos definidos en la unidad de traducción client.cpp también se definirán en la unidad de traducción main.cpp . Esta es una de las razones por las que normalmente no #include .cpp archivos .cpp .

Coloque la definición de su clase en un archivo client.hpp separado que no contenga también las definiciones de las funciones miembro de esa clase; luego, deje que client.cpp y main.cpp incluyan ese archivo (me refiero a #include ). Finalmente, deje en client.cpp las definiciones de las funciones de miembros de su clase.

client.h

#ifndef SOCKET_CLIENT_CLASS #define SOCKET_CLIENT_CLASS #ifndef BOOST_ASIO_HPP #include <boost/asio.hpp> #endif class SocketClient // Or whatever the name is... { // ... bool read(int, char*); // Or whatever the name is... // ... }; #endif

client.cpp

#include "Client.h" // ... bool SocketClient::read(int, char*) { // Implementation goes here... } // ... (add the definitions for all other member functions)

main.h

#include <iostream> #include <string> #include <sstream> #include <boost/asio.hpp> #include <boost/thread/thread.hpp> #include "client.h" // ^^ Notice this!

main.cpp

#include "main.h"

Sucedí que ya se definió en el error .obj. Esta es la estructura de mi proyecto:

main.cpp

#include "main.h";

main.h

#include <iostream> #include <string> #include <sstream> #include <boost/asio.hpp> #include <boost/thread/thread.hpp> #include "client.cpp"

client.cpp

#ifndef SOCKET_CLIENT_CLASS #define SOCKET_CLIENT_CLASS #ifndef BOOST_ASIO_HPP #include <boost/asio.hpp> #endif /*CLASS DEFINITION HERE*/ #endif

Esto es de lo que el compilador se queja:

main.obj: error LNK2005: "public: bool __thiscall SocketClient :: read (int, char *)" (? read @ SocketClient @@ QAE_NHPAD @ Z) ya definido en client.obj

Tenga en cuenta que se está quejando de mi clase, no aumenta. Una cosa interesante es que cuando #include <boost/asio.hpp> de client.cpp , obtengo errores porque también está incluido en main.h.

Como puede ver, no estoy definiendo / incluyendo mi clase, se incluye exactamente una vez en main.h. Entonces, ¿qué está pasando aquí?
He leído esta respuesta , pero no fue de ayuda, ya que espera inclusiones dobles. Toma este hecho en la osideración antes de votar por el duplicado, porque esto simplemente significa decapitarme sin piedad.


Probablemente no quieras hacer esto:

#include "client.cpp"

Un archivo * .cpp habrá sido compilado por el compilador como parte de su compilación. Al incluirlo en otros archivos, se compilará nuevamente (¡y nuevamente!) En cada archivo en el que lo incluya.

Ahora, esta es la #ifndef SOCKET_CLIENT_CLASS : lo está protegiendo con #ifndef SOCKET_CLIENT_CLASS , sin embargo, cada archivo que tiene #include "client.cpp" se #include "client.cpp" forma independiente y, como tal, encontrará SOCKET_CLIENT_CLASS aún no definido. Por lo tanto, sus contenidos se incluirán, no # ifdef''d out.

Si contiene alguna definición (en lugar de solo declaraciones), estas definiciones se repetirán en cada archivo en el que esté incluida.


Este es uno de los métodos para superar este problema.

  • Simplemente coloque el prototipo en los archivos de encabezado e incluya archivos de encabezado en archivos .cpp como se muestra a continuación. client.cpp

    ifndef SOCKET_CLIENT_CLASS

    define SOCKET_CLIENT_CLASS

    ifndef BOOST_ASIO_HPP

    incluir

    terminara si

    clase SocketClient // O cualquiera que sea el nombre ... {

    // ...

    bool read(int, char*); // Or whatever the name is...

    // ...};

    terminara si

client.h

bool SocketClient::read(int, char*) { // Implementation goes here... }

main.cpp

#include <iostream> #include <string> #include <sstream> #include <boost/asio.hpp> #include <boost/thread/thread.hpp> #include "client.h" // ^^ Notice this!

main.h

int main()