C++中为何不使用括号就无法调用类的成员函数?
解惑:为什么不能直接用
Cook.get_life(),而需要Cook().get_life()? 先把你的代码贴出来方便大家理解:
main.cpp
#include <iostream> #include "Cook.hpp" using namespace std; int main(void){ int l = Cook.get_life(); }
Cook.hpp
#ifndef HUNTER_H #define HUNTER_H class Cook { public: int get_life(void); private: int life; }; #endif
Cook.cpp
#include "Cook.hpp" int Cook::get_life(void) { life=0; return life; }
好了,咱们来拆解你遇到的问题:
核心原因:非静态成员函数必须绑定对象调用
你定义的get_life()是非静态成员函数,这类函数的本质是和具体的Cook对象绑定的——它需要访问对象内部的life成员变量(每个Cook对象都有自己的life值)。所以C++规定:非静态成员函数不能直接通过类名调用,必须先创建类的实例(对象),再通过对象来调用。
为什么Cook.get_life()报错?
Cook是类名,用类名.函数()的方式只能调用静态成员函数(用static修饰的函数)。静态函数属于整个类,不依赖任何对象,也不能访问非静态成员变量。而你的get_life()没有static修饰,还需要访问对象的life,所以直接用类名调用肯定会报错。
Xcode建议的Cook().get_life()为什么能正常运行?
Cook()其实是创建了一个临时的Cook对象,然后通过这个临时对象调用get_life(),完全符合非静态成员函数的调用规则。你也可以写成更清晰的形式:
int main(void){ Cook my_cook; // 创建一个有名字的Cook对象 int l = my_cook.get_life(); }
两种写法效果一致,只是临时对象在调用完函数后会自动销毁,而命名对象可以在后续代码中继续使用。
要是我就想通过类名调用,怎么办?
如果你确实需要Cook::get_life()这种调用方式,那得把函数改成静态成员函数,同时调整对应的成员变量(因为静态函数只能访问静态成员):
修改后的Cook.hpp:
#ifndef COOK_H // 顺便提一句,你原来的宏是HUNTER_H,建议改成COOK_H避免和其他头文件冲突 #define COOK_H class Cook { public: static int get_life(void); // 添加static修饰 private: static int life; // 成员变量也要改成静态,所有对象共享这一个值 }; #endif
修改后的Cook.cpp:
#include "Cook.hpp" int Cook::life = 0; // 静态成员变量必须在类外初始化 int Cook::get_life(void) { return life; }
此时main里就可以这样调用了:
int main(void){ int l = Cook::get_life(); // 静态成员函数用类名::调用 }
不过要注意:静态成员变量是所有Cook对象共享的,如果你希望每个厨师有自己的生命值,那还是用非静态的方式更合理。
内容的提问来源于stack exchange,提问作者RIEVER
相关产品推荐
相关产品推荐

