Неопределенная ссылка - ошибка компоновщика C ++ - PullRequest
2 голосов
/ 14 июля 2009

Я получаю сообщение об ошибке «Неопределенная ссылка» для этого оператора:

GlobalClass *GlobalClass::s_instance = 0;

Есть идеи? Код показан ниже:

=============================================== =

#ifndef GLOBALCLASS_H_
#define GLOBALCLASS_H_

#include <string>
class GlobalClass {

public:

    std::string get_value();

    void set_value(std::string);

    static GlobalClass *instance();

    static GlobalClass *s_instance;

private:

    std::string m_value;
};

#endif /* GLOBALCLASS_H_ */

===============================================

#include <string>
#include "GlobalClass.h"



/*
 GlobalClass(int v = 0)
 {
 m_value = v;
 }
 */

    static GlobalClass *s_instance;

    std::string GlobalClass::get_value()
    {
        return m_value;
    }

    void GlobalClass::set_value(std::string v)
    {
        m_value = v;
    }

    static GlobalClass *instance() {
        if (!s_instance)
            s_instance = new GlobalClass;
        return s_instance;
    }

=============================================== ============

#include <iostream>
#include "GlobalClass.h"

using namespace std;

int main() {

    GlobalClass::s_instance = 0;


    std::string myAddress = "abc";
    GlobalClass::instance()->set_value(myAddress);  \\ <=== compiler error
    std::cout << "====>address is is " << GlobalClass::instance()->get_value()
            << std::endl;
    return 0;
}

Ответы [ 3 ]

4 голосов
/ 14 июля 2009

Вы пытаетесь реализовать класс Singleton? То есть. Вам нужен только один экземпляр класса, и вы хотите, чтобы этот экземпляр был доступен каждому, кто включает этот класс. Я думаю, что его обычно называют Singleton, следующий пример работает как ожидалось:

Singleton.h:

#include <string>
class Singleton
{
public:
    static Singleton* instance()
    {
        if ( p_theInstance == 0 )
            p_theInstance = new Singleton;
        return p_theInstance;
    }
    void setMember( const std::string& some_string )
    {
        some_member = some_string;
    }
    const std::string& get_member() const
    {
        return some_member;
    }

private:
    Singleton() {}
    static Singleton* p_theInstance;
    std::string some_member;
};

Singleton.cpp:

Singleton* Singleton::p_theInstance = 0;

main.cpp:

#include <string>
#include <iostream>
#include "Singleton.h"

int main()
{
    std::string some_string = "Singleton class";
    Singleton::instance()->setMember(some_string);
    std::cout << Singleton::instance()->get_member() << "\n";
}

Обратите внимание, что конструктор является закрытым, мы не хотим, чтобы кто-либо создавал экземпляры нашего синглтона, кроме как с помощью оператора instance ().

3 голосов
/ 14 июля 2009

Когда вы объявляете статическое поле s_instance в своем файле .h, оно только сообщает компилятору, что это поле где-то существует. Это позволяет вашей функции main ссылаться на нее. Однако оно нигде не определяет поле, т. Е. Для него не зарезервирована память и ему не назначено начальное значение. Это аналогично разнице между прототипом функции (обычно в файле .h) и определением функции (в файле .cpp).

Чтобы действительно определить поле, вам нужно добавить следующую строку в ваш файл .cpp в глобальной области видимости (не внутри какой-либо функции):

GlobalClass* GlobalClass::s_instance = 0;

Важно, чтобы вы не добавляли модификатор static к этому определению (хотя у вас все равно должен быть модификатор static в объявлении внутри класса в файле .h). Когда определение вне класса помечено static, это определение может использоваться только внутри того же файла .cpp. Компоновщик будет действовать так, как будто он не существует, если он используется в других файлах .cpp. Это значение static отличается от static внутри класса и от static внутри функции. Я не уверен, почему разработчики языка использовали одно и то же ключевое слово для трех разных вещей, но это так.

0 голосов
/ 14 июля 2009

Если я понимаю, что вы хотите сделать, это только вопрос использования этого:

GlobalClass::s_instance = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...