Визначте статичний метод у вихідному файлі з оголошенням у заголовковому файлі на C ++


142

У мене виникають невеликі проблеми при роботі зі статичними методами в 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

Я не розумію, чому я не можу цього зробити. Хтось може допомогти мені зрозуміти, чому і як досягти того, що я хочу?


2
Перш за все, слід видалити staticключове слово у файлі .cpp. C ++ це не дозволяє.
Fezvez

10
@Fezvez: По черзі замініть його на /* static */. Мені подобається мати однакові модифікатори та аргументи за замовчуванням у файлах .h та .cpp.
Девід Торнлі

2
TL; DR: Тримайте staticу файлі заголовка .h, це означає "приєднаний до класу, а не до якогось об'єкта", видаліть staticу .cppфайлі, він має інше значення, якого ви тут не хочете.
Стефан Гурішон

Відповіді:


228

Видаліть staticключове слово у визначенні методу. Зберігайте це лише у визначенні вашого класу.

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


1
Так, зрозуміло, що staticу визначенні методу буде означати, що лише інші методи цього класу можуть отримати доступ до цього статичного методу, жодних інших методів поза цим класом.
ABV

14
Не інші методи класу, а інші функції у .cpp-файлі. Ви не повинні робити цього на C ++ у будь-якому випадку. Якщо ви хочете, щоб у функції C ++ був внутрішній зв'язок, слід розглянути можливість розміщення її в якомусь анонімному просторі імен. Використання static.cpp-файлів саме для зворотної сумісності з C.
x13n,

1
Тільки для цікавості ... Якщо я визначу статичного члена класу безпосередньо у класі (у файлі .h), як я можу використовувати статичну зв'язок?
мастило

Ви не можете. І цього немає сенсу робити, оскільки з'єднання програми разом призвело б до появи невирішених зовнішніх програм.
x13n

41

Ключові слова staticі virtualне повинні повторюватися у визначенні. Вони повинні використовуватися лише в декларації класу.


11

Вам не потрібно мати staticвизначення функції


-3

Статичні функції члена повинні посилатися на статичні змінні цього класу. Тож у вашому випадку,

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

Оскільки функція вашого члена CP_StringToPstringє статичною, параметри в цій функції inStringтакож outStringповинні бути оголошені як статичні.

Функції статичного члена не посилаються на об'єкт, над яким він працює, але змінні, які ви декларували, посилаються на його поточний об'єкт, тому він повертає помилку.

Ви можете або видалити статику з функції члена, або додати статику, оголошуючи параметри, які використовувались для функції члена, також статичними.


2
inString і outString - аргументи статичної функції. Вони не є членами класу. Не потрібно перетворювати їх на статичні.
999к

Це зовсім не правильно. Ви можете розміщувати нестатичні аргументи у функції статичного члена. Але для членів класу ви можете отримувати доступ / змінювати лише статичні функції.
Захарій Краус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.