2013-07-15 4 views
2

Я пытаюсь инициализировать статический член класса и не повезло. Вот тест:Инициализация статического члена класса

файл test.h

#include <string> 

class Test { 

public: 
    static void init(char*); 

private: 
    static std::string *sp; 

}; 

файл test.cpp

#include "Test.h" 

// Initialize the class 
void 
Test::init(char *foo) { 
    Test::sp = new std::string(foo); 
} 

int main(int argc, char** argv) { 
    Test::init(argv[1]); // call the class initializer 
} 

линкер выдает:

Undefined symbols for architecture x86_64: 
    "Test::sp", referenced from: 
     Test::init(char*) in Test-OK13Ld.o 
ld: symbol(s) not found for architecture x86_64 

В реальном мире, Init() собирается сделать некоторую реальную работу, чтобы установить статический член. Может кто-нибудь указать на ошибку?

+0

'статическими станд :: строка * зр;' не difined. – user1810087

+0

также, зачем использовать указатель на std :: string? – billz

+0

Ну, я знаю, что такое неопределенный ref/unresolved extern, так что ссылка довольно широкая. Комментарий @itwasntpete напомнил мне, что все, что у меня есть, - это декларация. Поэтому, по-видимому, мне нужно определение (но вне) определения класса. – Chap

ответ

1

Это немного неловко «особенности» C++: вам нужно сделать некоторую руку, чтобы убедиться, что линкер может генерировать символы. Вам нужно выбрать файлcpp, и убедитесь, что для этих же символов в любом другом случае нет такого ручного удерживания (иначе линкер не сработает, когда он встретит дубликаты символов). Таким образом, вы должны сделать еще одно объявление статических переменных-членов для вашего класса в cpp файл, как это:

std::string * Test::sp; // or sp = NULL; 
+0

Ах - разница между декларацией и определением. Я никогда не думал о том, где именно будет жить эта статика; Я просто предположил, что C++ позаботится о вещах. Стоит упомянуть (если это так!), Что определение (или это другое объявление?) Должно быть вне любых функций в файле .cpp. – Chap

+0

Это действительно * * уродливый! Если он написан как оператор присваивания, в какой момент он выполняется? – Chap

+0

Ну, вот где термин «статичное фиаско порядка инициализации» возвращает свою уродливую голову. В принципе, до основного, но когда точно зависит от всех других 'статических' переменных, и вы действительно, действительно не хотите зависеть от этого. Так что не делайте волосатые вещи до 'main', если вы можете избежать этого (что почти всегда). Единственная точка установки указателя на «NULL» заключается в том, что вы можете проверить, было ли оно еще «настроено» функцией init. – user268396

1

Как сказано в сообщении об ошибке, static std::string *sp; должно быть определено где-то, поскольку оно не связано ни с одним экземпляром class Test.

Добавление его test.cpp в глобальном масштабе будет решить проблему:

std::string *Test::sp = NULL; 
Смежные вопросы