问题描述
我是 C++ 的新程序员。我遇到了一个问题,我无法理解这一点。你能帮我弄清楚吗?这是本书的一个例子,
class TextQuery {
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(std::ifstream &);
QueryResult query(const std::string &) const;
private:
std::shared_ptr<std::vector<std::string>> file;
std::map<std::string,std::shared_ptr<std::set<line_no>>> wm;
//static std::string cleanup_str(const std::string &); // the book example uses 'static'
std::string cleanup_str(const std::string &); // I think 'static' key word is not needed.so i remove it.
};//class declearation ends here.
std::string TextQuery::cleanup_str(const std::string &word) {
string ret;
for(auto it = word.begin();it != word.end();++it){
if(!ispunct(*it))
ret += tolower(*it);
}
return ret;
}
QueryResult TextQuery::query(const std::string &sought) const
{
static shared_ptr<set<line_no>> nodata(new set<line_no>); //line 66
auto loc = wm.find(cleanup_str(sought)); //line 67
if(loc == wm.end())
return QueryResult(sought,nodata,file);
else
{
return QueryResult(sought,loc->second,file);
}
}
我不能不规范删除“静态”关键字的版本与没有的版本之间的区别。编译错误是:
passing 'const TextQuery' as 'this' argument discards qualifiers [-fpermissive],67
the object has type qualifiers that are not compatible with the member function "TextQuery::cleanup_str" -- object type is: const TextQuery,67
我尝试了两种可以正常工作的方法:
- 将
'static'
添加到函数cleanup_str
。我无法理解为什么它可以通过。 - 我尝试的另一种方法是:删除函数
'const'
的最后一个QueryResult TextQuery::query(const std::string &sought) const
关键字,使其变为:QueryResult TextQuery::query(const std::string &sought)
。这个方法有效,我也搞不懂这个原因。
解决方法
const
方法有一个约定——它不会改变类实例的内部状态。从技术上讲,它的实现方式是隐藏参数 this
具有类型 const TextQuery *
- 指向 TextQuery
的常量(不可修改)对象的指针。要遵循该约定,您不能调用 非常量 方法,它可能会修改原始 const 方法的内部状态和制动约定。现在 -
在函数cleanup_str 中添加'static'。我不明白为什么它可以通过。
静态方法不适用于实例,它只属于那个类(它根本没有隐藏参数 this
)因此从 const
方法调用这样的方法是安全的,合同不会被打破。如果您删除 static
,那么该方法将成为常规的非 const 方法,并且从 const
调用它是不安全的。
我尝试的另一种方法是:删除函数 QueryResult 的最后一个 'const' 关键字
现在您的方法 query
变为非常量(this
的类型为 TextQuery *
),因此可以安全地从中调用非常量或静态方法。所以你的编译器错误消失了。