Search code examples
c++googletestsubclassing

Link error when subclassing string


for various reasons I subclassed the std::string like:

   class CotengString : public string
         {
        public:
        // Constructors
        CotengString();
        CotengString(const char* ch) : string(ch) {}
        CotengString(const string& str) : string(str) {}
        virtual ~CotengString() {};

        //Operator"="
        CotengString& operator=(const string& str) { return (CotengString&)this->assign(str); }
        CotengString& operator=(const char* ch) { return (CotengString&)this->assign(ch); }
    };

Inside the DLL I wish to use this code all compiles correctly. But inside my Google Test project I get this error after switching to the subclassed string

LNK2005 "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(char const *,unsigned int)" (??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBDI@Z) already defined in gtest.lib(gtest-all.obj)    Devices.Spectro.CppTest <path>\Devices.Spectro.CppTest\Devices.Spectro.Cpp.lib(Devices.Spectro.Cpp.dll)

My gut feeling is that I am missing something obvious. But I don't know what it could be


Solution

  • Okay, then as answer.

    First cause

    This seems to me to be a problem of multiple includes of header files. This results in that the compiler wants to compile functions or in this case allocators again and detects "oh I already compiled that!".

    So fix would be to add to the header file this:

    #ifndef CUSTOM_STRING_IMPLEMENTATION_HEADER
    #define CUSTOM_STRING_IMPLEMENTATION_HEADER
    
    ....
    
    #endif
    

    Second cause

    However, if this isn't the case maybe you're trying to compile this file again in your code which uses the dll which already contains the compiled class.

    I personally think it's the second cause according to your log file. There's said that the allocator is already compiled in your library.

    Example:

    If you're using only header files this results in a big problem. Look here.

    Dll code:

    SomeHeaderFile.hpp

    class NiceClass{
    //Constructor is implemented. That causes several problems now! 
    NiceClass{
    
     }
    ...
    }
    

    Your application code (wich uses the dll):

    SomeNiceApplicationCode:

    //Linker error now! It's already compiled right into your dll!
    #include <SomeHeaderFile.hpp>
    
    int main(){
       NiceClass niceClassInstance;
       return 0;
    }
    

    Solution:

    Apply those changes and create and extra cpp file for your class.

    Include in your application file only the header file.

    class CotengString : public string
         {
        public:
        // Constructors
        CotengString();
        CotengString(const char* ch) : string(ch); //Use cpp file!
        CotengString(const string& str) : string(str); //""
        virtual ~CotengString(); //""
    
        //Operator"="
        CotengString& operator=(const string& str); //Same for this
        CotengString& operator=(const char* ch); //""
    };