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()