Xác định phương thức tĩnh trong tệp nguồn với khai báo trong tệp tiêu đề trong C ++


142

Tôi gặp một chút khó khăn khi làm việc với các phương thức tĩnh trong C ++

Ví dụ .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);

};

Ví dụ .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;
    }
}

Tôi muốn thực hiện một cuộc gọi như:

IC_Utility::CP_StringToPString(directoryNameString, directoryName );

Nhưng tôi gặp một lỗi:

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

Tôi không hiểu tại sao tôi không thể làm điều này. Bất cứ ai có thể giúp tôi hiểu tại sao và làm thế nào để đạt được những gì tôi muốn?


2
Trước hết, bạn nên xóa statictừ khóa trong tệp .cpp. C ++ không cho phép nó.
Fezvez

10
@Fezvez: Thay thế, thay thế bằng /* static */. Tôi thích có cùng các sửa đổi và đối số mặc định trong các tệp .h và .cpp.
David Thornley

2
TL; DR: Giữ statictrong tệp tiêu đề .h, nó có nghĩa là "được gắn vào lớp, không phải với bất kỳ đối tượng nào", xóa statictrong .cpptệp, nó có một ý nghĩa khác mà bạn không muốn ở đây.
Stéphane Gourichon

Câu trả lời:


228

Xóa statictừ khóa trong định nghĩa phương thức. Giữ nó chỉ trong định nghĩa lớp học của bạn.

statictừ khóa được đặt trong tệp .cpp có nghĩa là một hàm nhất định có liên kết tĩnh, nghĩa là. nó chỉ có thể truy cập từ các chức năng khác trong cùng một tệp.


1
À, hiểu rồi nên statictrong định nghĩa phương thức sẽ chỉ có nghĩa là các phương thức khác trong lớp đó có thể truy cập phương thức tĩnh đó, không có phương thức nào khác ngoài lớp đó.
ABV

14
Không phải các phương thức lớp khác, nhưng các hàm khác trong tệp .cpp. Bạn không nên làm điều này trong C ++. Nếu bạn muốn một hàm C ++ có liên kết nội bộ, bạn nên xem xét việc đặt nó trong một số không gian tên ẩn danh. Việc sử dụng các statictệp .cpp chỉ để tương thích ngược với C.
x13n

1
Chỉ vì tò mò ... Nếu tôi định nghĩa một thành viên lớp tĩnh trực tiếp trong lớp (trong tệp .h), làm thế nào tôi có thể sử dụng liên kết tĩnh?
thắt lưng

Bạn không thể. Và thật vô nghĩa khi làm như vậy, vì việc liên kết chương trình với nhau sẽ khiến các phần bên ngoài chưa được giải quyết xuất hiện.
x13n

41

Từ khóa staticvirtualkhông nên được lặp lại trong định nghĩa. Chúng chỉ nên được sử dụng trong khai báo lớp.


11

Bạn không cần phải có staticđịnh nghĩa hàm


-3

Các hàm thành viên tĩnh phải tham chiếu đến các biến tĩnh của lớp đó. Vì vậy, trong trường hợp của bạn,

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

Vì hàm thành viên của bạn CP_StringToPstringlà tĩnh, nên các tham số trong hàm đó inStringoutStringcũng được khai báo là tĩnh.

Các hàm thành viên tĩnh không tham chiếu đến đối tượng mà nó đang làm việc nhưng các biến mà bạn khai báo đề cập đến đối tượng hiện tại của nó để nó trả về lỗi.

Bạn có thể loại bỏ tĩnh khỏi hàm thành viên hoặc thêm tĩnh trong khi khai báo các tham số bạn đã sử dụng cho hàm thành viên là tĩnh.


2
inString và outString là các đối số của hàm tĩnh. Họ không phải là thành viên trong lớp. Không cần phải chuyển đổi chúng thành tĩnh.
999k

Điều đó không đúng chút nào. Bạn có thể đặt các đối số không tĩnh trong hàm thành viên tĩnh. Nhưng với các thành viên trong lớp, bạn chỉ có thể truy cập / sửa đổi các hàm tĩnh trong hàm.
Zachary Kraus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.