C++ 非法调用非静态成员函数

C++ 非法调用非静态成员函数,c++,visual-c++,C++,Visual C++,我在以下函数中遇到问题: 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++; in

我在以下函数中遇到问题:

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;
}
声明:

char* GetPlayerNameEx(int playerid);
用法:

sprintf(string, "%s", CPlayer::GetPlayerNameEx(playerid));
现在我的问题是

删除个人信息

如果这与它有任何关系,我怀疑它与此有关,那么此函数包含在“类”标题(declaration)中

我也不知道为什么,但我不能让“代码”框正确匹配

CPlayer::GetPlayerNameEx(playerid)
不能对类类型使用scope(
)运算符调用函数,除非它是静态函数。要在对象上调用函数,实际上必须首先为该对象创建内存(通过在某处生成
CPlayer
变量),然后在该对象上调用函数


静态函数是全局函数,特别是不会弄乱类的成员变量(除非它们也是静态的)这使得它们可以在没有实际对象实例范围的情况下有效调用。

非法调用非静态成员函数意味着您试图在不使用包含该函数的类的对象的情况下调用该函数

解决方案应该是使函数成为静态函数

这通常是导致错误C2352的原因:

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

int main() {
    MyClass::MyFunc();   // C2352
    MyClass::MyFunc2();   // OK
}
如果您不能选择将其设置为静态,则必须创建类CPlayer的实例

像这样:

CPlayer myPlayer;
myPlayer.GetPlayerNameEx(playerid);

您无法将这些函数创建为静态函数(无需进行大量调整),因为您正试图修改特定实例的数据。要解决您的问题,请执行以下操作:

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));


你有。无论如何,我会返回一个
std::string
。函数GetPlayerNameEx是在CPlayer名称空间中声明的还是CPlayer是类名?@chris:根据编译器的说法,OP的程序实际上格式不正确。要发生未定义的行为,必须先编译并运行。您必须声明该函数
static
。支持该代码以删除“Name”中的下划线,我不能返回pName。当您需要调用静态函数时,将使用scope运算符,所以OP声明函数是静态的,它应该工作。Banex声明为静态决定返回相同的错误,这就是为什么我感到困惑的原因。->fundation也会返回类似的错误。当我使用::时,函数出现在下拉列表中。@user1591117请确保仅在类声明所在的标题中放置static关键字。scope运算符更具体地说是一种声明下一条语句使用哪个作用域的方法,不一定只用于调用静态方法。如果函数调用另一个非静态函数或在其中使用非静态变量,则不能将函数设置为静态。是的,使用->是取消引用对象,不能对类类型执行此操作,实际上必须先设置对象
CPlayer*myPlayer=newcplayer;myPlayer->GetPlayerNamex(playerid)
可以工作,但在我看来,该函数应该是静态的,因为它并不真正关心哪个玩家在调用它。@Lochemage,只是它会不必要地使用指针。@Lochmage:这正是我不理解的,因为我输入的任何玩家ID都应该处理它。我很乐意这样做,让这个全球性的问题得到解决;然而,这需要重新定义相当多的代码。@chris我只是解释了为什么他不能在类类型上使用->以及如何使用->来调用函数,而不是他应该这样做。我甚至在结尾说,根据他的函数的用途判断,他更可能打算使用静态方法。@user1591117当你在什么特定对象上进行操作或不打算创建对象时,你使用静态方法。例如,如果您的
CPlayer
类仅是一个玩家,并且您的函数旨在搜索所有玩家,而不管哪个玩家调用该函数,那么是的,您希望它是静态的。但是,如果您只希望该函数对调用它的实际播放机做出反应,那么您就不希望了。这会删除静态错误,但会给我带来对话错误。我相信我可以调整和处理这个。谢谢:D。好的,未经测试,但是我已经得到了这项工作,感谢您发布的代码;谢谢你和大家的帮助D@Neil:是的。我没有解决这个问题(主要是静态问题)。为了完整性,我会更正它。