2013-08-22 41 views
5

Tôi đang gặp rắc rối với chức năng dưới đây:cuộc gọi trái phép hàm thành viên không tĩnh

char* GetPlayerNameEx(int playerid) 
{ 

    char Name[MAX_PLAYER_NAME], i = 0; 

    GetPlayerName(playerid, Name, sizeof(Name)); 

    std::string pName (Name); 

    while(i == 0 || i != pName.npos) 
    { 
     if(i != 0) i++; 
     int Underscore = pName.find("_", i); 
     Name[Underscore] = ' '; 
    } 
    return Name; 
} 

khai:

char* GetPlayerNameEx(int playerid); 

sử dụng:

sprintf(string, "%s", CPlayer::GetPlayerNameEx(playerid)); 

Bây giờ vấn đề của tôi ở đây là

Thông tin cá nhân bị xóa n.

Nếu điều này có bất cứ điều gì để làm với nó mà tôi nghi ngờ nó, chức năng này được chứa trong một tiêu đề "Class" (Declartion).

Ngoài ra tôi không biết tại sao nhưng tôi không thể nhận được hộp "Mã" để vừa với chính xác.

+1

Bạn có [hành vi undefined] (http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) . Tôi sẽ trả về một 'std :: string'. – chris

+0

Chức năng GetPlayerNameEx có được khai báo bên trong không gian tên CPlayer hay là tên lớp CPlayer? – Amadeus

+1

@chris: theo trình biên dịch, chương trình của OP là trên thực tế không thành lập. Đối với một hành vi không xác định xảy ra, nó nhất thiết phải biên dịch và chạy đầu tiên. –

Trả lời

4

Bạn không thể tạo các chức năng như tĩnh (mà không có nhiều tinh chỉnh) bởi vì bạn đang cố gắng sửa đổi dữ liệu của một trường hợp cụ thể. Để khắc phục vấn đề của bạn:

class CPlayer 
{ 
public: 
    // public members 

    // since you are operating on class member data, you cannot declare these as static 
    // if you wanted to declare them as static, you would need some way of getting an actual instance of CPlayer 
    char* GetPlayerNameEx(int playerId); 
    char* GetPlayerName(int playerId, char* name, int size); 
private: 
    // note: using a std::string would be better 
    char m_Name[MAX_PLAYER_NAME]; 
}; 

// note: returning a string would be better here 
char* CPlayer::GetPlayerNameEx(int playerId) 
{ 
    char* Name = new char[MAX_PLAYER_NAME]; 
    memset(Name, MAX_PLAYER_NAME, 0); 
    GetPlayerName(playerId, m_Name, sizeof(m_Name)); 
    std::string sName(m_Name); 
    std::replace(sName.begin(), sName.end(), '_', ' '); 
    ::strncpy(sName.c_str(), Name, MAX_PLAYER_NAME); 
    return Name; 
} 
// in your usage 
CPlayer player; 
// ... 
sprintf(string, "%s", player.GetPlayerNameEx(playerid)); 
+0

Điều này sẽ loại bỏ lỗi tĩnh, tuy nhiên, cho tôi lỗi hội thoại. Tôi chắc chắn rằng tôi có thể tinh chỉnh và làm việc với điều này. Cảm ơn: D. – user1591117

+1

Bạn vẫn đang trả về một con trỏ tới một mảng cục bộ. –

+0

Được rồi chưa được kiểm tra tuy nhiên tôi đã nhận được lời cảm ơn này đối với mã mà bạn đã đăng; cảm ơn vì bạn và mọi người giúp đỡ ở đây. : D – user1591117

2
CPlayer::GetPlayerNameEx(playerid) 

Bạn không thể sử dụng toán tử phạm vi (::) trên loại lớp để gọi hàm trừ khi đó là hàm tĩnh. Để gọi một hàm trên một đối tượng, trước tiên bạn phải tạo bộ nhớ cho đối tượng đó (thông qua tạo một biến CPlayer ở đâu đó) và sau đó gọi hàm trên đối tượng đó.

Chức năng tĩnh là toàn cầu và không gây rối với biến thành viên của lớp (trừ khi chúng cũng tĩnh), điều này làm cho chúng hợp lệ để gọi mà không có phạm vi của một đối tượng thực tế.

+0

Có, sử dụng -> là de-tham chiếu đối tượng, bạn không thể làm điều đó trên một loại lớp, bạn thực sự có để làm cho đối tượng đầu tiên. 'CPlayer * myPlayer = CPlayer mới; myPlayer-> GetPlayerNameEx (playerid); 'sẽ hoạt động, nhưng âm thanh với tôi như chức năng đó chỉ nên tĩnh, vì nó không thực sự quan tâm người chơi đang gọi nó là gì. – Lochemage

+0

@Lochemage, Ngoại trừ nó sẽ sử dụng con trỏ khá không cần thiết. – chris

+0

@Lochmage: Đó chính xác là những gì tôi không hiểu vì bất kỳ playerid nào tôi nhập vào cũng nên xử lý nó. Làm cho toàn cầu này chiếu sáng vấn đề, vì tôi rất vui khi làm điều đó; tuy nhiên sau đó nó sẽ yêu cầu xác định lại khá một mã số. – user1591117

5

Cuộc gọi không hợp lệ của chức năng thành viên không tĩnh có nghĩa là bạn đang cố gắng gọi hàm mà không cần sử dụng đối tượng của lớp có chứa hàm.

Giải pháp nên làm cho chức năng trở thành một hàm tĩnh.

Đây là bình thường những gì làm cho C2352 lỗi:

class MyClass { 
    public: 
     void MyFunc() {} 
     static void MyFunc2() {} 
}; 

int main() { 
    MyClass::MyFunc(); // C2352 
    MyClass::MyFunc2(); // OK 
} 

Nếu làm cho nó tĩnh không phải là một lựa chọn cho bạn, sau đó bạn phải tạo một thể hiện của các CPlayer lớp.

Như thế này:

CPlayer myPlayer; 
myPlayer.GetPlayerNameEx(playerid); 
+0

Toán tử phạm vi được sử dụng khi bạn cần gọi hàm tĩnh, vì vậy hàm OP khai báo hàm đó là tĩnh nên nó hoạt động. – Banex

+0

Banex tuyên bố là tĩnh quyết định trả lại cùng một lỗi, đó là lý do tại sao tôi bối rối. -> fundtion aswell trả về các lỗi tương tự. Khi tôi sử dụng :: hàm xuất hiện trong menu thả xuống. – user1591117

+0

@ user1591117 hãy đảm bảo đặt từ khóa tĩnh trong tiêu đề nơi khai báo lớp. – Banex

Các vấn đề liên quan