[solved] Problem with creating a static variable in my class



  • I have created a small class in Qt that does nothing, and declared a static variable in the .h file, and tried to reference that static variable from within the cpp file. I get an "Undefined symbol" error. The two files are:

    ============== .h =============
    @
    #ifndef TESTMECLASS_H
    #define TESTMECLASS_H

    #include <QString>

    class TestMeClass

    {
    public:
    TestMeClass();
    static QString myString;
    };
    #endif // TESTMECLASS_H
    @

    =========== .cpp ===============
    @
    #include "testmeclass.h"

    TestMeClass::TestMeClass()
    {
    TestMeClass::myString.append("This string");
    }
    @

    compilation output:

    Undefined symbols:
    "TestMeClass::myString", referenced from:
    __ZN11TestMeClass8myStringE$non_lazy_ptr in testmeclass.o
    ld: symbol(s) not found

    Any idea? Not sure why this is not working.

    Thanks for any help...
    Bruce

    [Edit: markup fixed / Denis Kormalev]



  • You need to declare the string elsewhere as well. For example, in your .cpp add:

    @QString TestMeClass::myString;@

    Jeremy





  • jeremy_c answered it correctly, but to make it easy for future visitors on this thread I'm putting this corrected code.

    @#include "testmeclass.h"

    QString TestMeClass::myString;

    //You can initialize it as well.
    //QString TestMeClass::myString = "Some Starting Value";

    TestMeClass::TestMeClass()
    {
    TestMeClass::myString.append("This string");
    }@



  • Thanks a lot. That clears that up. I looked further to find it turns out that the issue in C++ is that static variables declared in a class declaration are not actually instantiated on creating an object of that class type. The declaration that Jeremy gave in the .cpp class is actually the instantiation of that variable. That is why, even if that static variable were declared private, the "external" declaration could still be used to initialize the variable. In other words, that class could have been defined as:

    class TestMeClass

    {
    private:
    TestMeClass();
    public:
    static QString myString;
    };

    with an instantiation in the .cpp file of

    QString TestMeClass::myString = "";

    and the initialization would have worked. I tried this and it actually does work. You two guys probably already know this, but it's news to me.

    Thanks again...
    Bruce


  • Moderators

    ... but only if TestMeClass is in a header file that is included exactly in one place. Otherwise you will get linker errors.

    The issue is that this static variable needs to be living in exactly one of the generated object files (or the linker will complain about multiple or missing definitions). The object file containing the instanciation will be that home. So if you put it into a header file and include that into several other files you get several homes for that variable.



  • Right, which is why I was having that instantiation in the .cpp file. Good point.


  • Moderators

    Oh, I missed that part. Your posting would be more readable if it used the code tags!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.