为什么函数 cleanup_str 必须用 'static' 关键字限定?

why the function cleanup_str must be qualified with 'static' key word?

我是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);
    }  
}

我无法区分去除'static'关键字和不去除关键字的版本之间的区别。编译错误为:

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

我试过两种可以正常工作的方法:

  1. 'static'添加到函数cleanup_str。我不明白为什么它可以通过。
  2. 我尝试的另一种方法是:删除函数QueryResult TextQuery::query(const std::string &sought) const的最后一个'const'关键字,使其成为:QueryResult TextQuery::query(const std::string &sought)。而且这个方法行得通,我也无法理解这个原因。

const 方法有一个契约——它不会改变 class 实例的内部状态。从技术上讲,它的实现方式是隐藏参数 this 具有类型 const TextQuery * - 指向 TextQuery 的常量(不可修改)对象的指针。要遵循该合同,您不能调用 non constant 方法,它可能会修改原始 const 方法的内部状态和制动合同。现在-

add 'static' to the function cleanup_str. I cannot unstand why it can pass.

静态方法不适用于实例,它只属于那个class(它根本没有隐藏参数this)因此从[=调用这样的方法是安全的10=]方法,契约不会被破坏。如果你删除 static 那么那个方法就变成了常规的 non const 方法并且从 const one.

中调用它是不安全的

The other way I tried is: remove the last 'const' key word of function QueryResult

现在你的方法 query 变成非常量(this 的类型是 TextQuery *)所以从它调用非常量或静态方法是安全的。所以你的编译器错误消失了。