Определить статический метод в исходном файле с объявлением в заголовочном файле на C ++

145

У меня небольшие проблемы с работой со статическими методами в C ++

Пример .h:

class IC_Utility {
public:
    IC_Utility();
    ~IC_Utility();

    std::string CP_PStringToString( const unsigned char *outString );
    void CP_StringToPString( std::string& inString, unsigned char *outString, short inMaxLength );
    static void CP_StringToPString( std::string& inString, unsigned char *outString);
    void CP_StringToPString( FxString& inString, FxUChar *outString);

};

Пример .cpp:

static void IC_Utility::CP_StringToPString(std::string& inString, unsigned char *outString)
{
    short       length = inString.length();

   if( outString != NULL )
    {
        if( length >= 1 )
            CPLAT::CP_Utility::CP_CopyMemory( inString.c_str(), &outString[ 1 ], length );

            outString[ 0 ] = length;
    }
}

Я хотел позвонить так:

IC_Utility::CP_StringToPString(directoryNameString, directoryName );

Но получаю ошибку:

error: cannot declare member function 'static void IC_Utility::CP_StringToPString(std::string&, unsigned char*)' to have static linkage

Я не понимаю, почему я не могу этого сделать. Может ли кто-нибудь помочь мне понять, почему и как достичь того, чего я хочу?

ABV
источник
2
Прежде всего, вам следует удалить staticключевое слово из файла .cpp. C ++ этого не допускает.
Б. Декостер
10
@Fezvez: Или замените его на /* static */. Мне нравятся одинаковые модификаторы и аргументы по умолчанию в файлах .h и .cpp.
Дэвид Торнли
2
TL; DR: сохранить staticв файле заголовка .h, это означает «прикреплен к классу, а не к какому-либо объекту», удалить staticв .cppфайле, это имеет другое значение, которое вам здесь не нужно.
Стефан Гуришон

Ответы:

234

Удалить staticключевое слово в определении метода. Сохраните это только в определении вашего класса.

staticключевое слово, помещенное в файл .cpp, означает, что у определенной функции есть статическая связь, т.е. он доступен только из других функций в том же файле.

x13n
источник
1
Ах, понял, что staticопределение метода будет означать, что только другие методы в этом классе могут получить доступ к этому статическому методу, и никакие другие методы вне этого класса.
ABV
14
Не другие методы класса, а другие функции в файле .cpp. В любом случае вам не следует делать это на C ++. Если вы хотите, чтобы функция C ++ имела внутреннюю связь, вам следует подумать о ее размещении в каком-либо анонимном пространстве имен. Использование staticв .cpp файлов только для обратной совместимости с С.
x13n
1
Просто из любопытства ... Если я определю статический член класса непосредственно в классе (в файле .h), как я могу использовать статическую связь?
lumbric
Вы не можете. И в этом нет смысла, поскольку связывание программы вместе вызовет появление неразрешенных внешних элементов.
x13n 08
42

Ключевые слова staticи virtualне должны повторяться в определении. Их следует использовать только в объявлении класса.

Бо Перссон
источник
12

Вам не нужно staticуказывать определение функции

cpx
источник
0

Вероятно, лучший способ действий - «делай это так, как это делает std lib». То есть: все в строке, все в заголовках.

// in the header
namespase my_namespace {

   class my_standard_named_class final {
public:
         static void standard_declared_defined_method () {
            // even the comment is standard
         }
   } ;

} // namespase my_namespace 

Так просто, как, что ...

Повар-гладиатор
источник
-4

Статические функции-члены должны ссылаться на статические переменные этого класса. Итак, в вашем случае

static void CP_StringToPString( std::string& inString, unsigned char *outString);

Так как ваша функция - член CP_StringToPstringявляется статическим, параметры в этой функции, inStringи outStringдолжны быть объявлены как статические тоже.

Статические функции-члены не относятся к объекту, над которым он работает, но объявленные вами переменные относятся к его текущему объекту, поэтому он возвращает ошибку.

Вы можете либо удалить статику из функции-члена, либо добавить статику, объявив параметры, которые вы использовали для функции-члена, как статические.

Принц Алоис
источник
2
inString и outString - аргументы статической функции. Они не члены класса. Преобразовывать их в статические нет необходимости.
999k
Это совсем не правильно. Вы можете поместить нестатические аргументы в статическую функцию-член. Но из членов класса вы можете получить доступ / изменить только статические в функции.
Zachary Kraus