Thread: VC++ error LNK2005 (class in extern. file)

  1. #1
    C = C - 1
    Join Date
    Mar 2008
    Posts
    15

    VC++ error LNK2005 (class in extern. file)

    the MS VC++ 2008 express edition compiler gives a strange linker error message:
    Error 1 error LNK2005: "public: void __thiscall Class::function(int)" (?function@Class@@QAEXH@Z) already defined in class.obj main.obj
    without any apparent reason. I wrote the following (simple) example to demonstrate the problem:

    main.cpp:
    Code:
    #include "class.cpp"
    
    int main()
    {
        Class someclass;
        someclass.function(10);
    }
    class.cpp:
    Code:
    #include <iostream>
    using namespace std;
    
    class Class
    {
    public:
        void function(int);
    };
    
    void Class::function(int number)
    {
        cout << "the number was: " << number << endl;
        cin.get();
    }
    it compiles fine using dev-cpp 5.0.

    sorry for my bad english...
    Thanks

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    This is because you are not using #include properly. By doing it the way you are doing things, the code for the Class object exists in both main.cpp/obj and in class.cpp/obj. The linker then sees the same code in two different places and spits out the error you see. You should only #include the class interface, not the actual code file, i.e. create a header (.h) file called class.h:

    Code:
    #ifndef CLASS_H
    #define CLASS_H
    class Class
    {
    public:
        void function(int);
    };
    #endif
    You class.cpp file should only be:
    Code:
    #include "class.h"
    #include <iostream>
    void Class::function(int number)
    {
        std::cout << "the number was: " << number << std::endl;
        std::cin.get();
    }
    Then your main.cpp should be:
    Code:
    #include "class.h"
    
    int main()
    {
        Class someclass;
        someclass.function(10);
    }

    It compiles fine because individually the two separate source files are fine. It's the linkers job to combine all the separate object files into a single executable file and this is where the duplicate code causes problems.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Never include .cpp files. Put your class definition in a header file and include that instead.
    Dev-C++ was wrong to compile at all.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    C = C - 1
    Join Date
    Mar 2008
    Posts
    15
    ok thanks for help
    odd that dev-cpp didn't give any warnings at all...

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    There is nothing wrong with the lack of warnings in this instance. The compiler does its job with the information it's given... in this case, it compiles (separately) the two source files into two object files. These files are fine individually. The problem comes when the linker tries to combine the two object files into a single executable that the duplicate code problem comes into play. You may have avoided problems here also by removing class.cpp from the project (but I wouldn't recommend this in this case), then the compiler would not touch it all and you'd essentially have a single source project to compiler/link and the #include directive would have worked (although not as intended for a source file).
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    C = C - 1
    Join Date
    Mar 2008
    Posts
    15
    ok so the preprocessor will place the header code in place of the #include directive causing the file

    class.cpp look like this:
    Code:
    class Class
    {
    public:
        void function(int);
    };
    ...iostream...
    /*also is it better to simply set std as a default namespace so the compiler places that
    reference by default, or use a reference to the namesp. directly like std::?
     how mutch similar coding will affect to compile time in large projects?*/
    
    void Class::function(int number)
    {
        std::cout << "the number was: " << number << std::endl;
        std::cin.get();
    }
    and main.cpp like:
    Code:
    class Class
    {
    public:
        void function(int);
    };
    
    int main()
    {
        Class someclass;
        someclass.function(10);
    }
    right?

    but how does the linker link the object files together differently with that additional declaration? help plz I'm a newbie in c++... thaks

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It searches all your object files (*.obj, *.o, etc) for the specified symbol, in this case, the name of your function in the class.
    The definition is there only so the compiler can see how the class looks like.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    C = C - 1
    Join Date
    Mar 2008
    Posts
    15

    Thumbs up one last question...

    Is it poissible to initialize a multidimensional array located in a class in a way that i can set it's bounds as a constructor parameter? I mean like:

    Code:
    class Class
    {
    public:
    	Class(int, int);
    private:
        const int x_res, y_res;
        int array[y_res][x_res]; //obviously doesn't work...
    };
    Class::Class(int x, int y):x_res(x), y_res(y) {}
    anyways thanks for help !

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You are looking for a dynamically sized multi-dimensional array. Use a vector of vectors for the simplest solution.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 10:39 PM
  2. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  3. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  4. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM