【问题标题】:why the function cleanup_str must be qualified with 'static' key word?为什么函数 cleanup_str 必须用“静态”关键字限定?
【发布时间】:2021-02-01 05:03:08
【问题描述】:

我是 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

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

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

【问题讨论】:

  • 由于cleanup_str 没有对TextQuery 类的任何实例做任何事情,似乎没有任何理由让它成为非静态类成员函数。这个决定有什么原因吗?
  • 编译器告诉你的是queryconst成员函数,不能调用非常量成员函数。所以要么将cleanup_str 也设为const,或者在这种情况下最好设为static,因为它没有充分的理由成为非静态的。
  • @DavidSchwartz 这是教科书中的一个例子。对我来说,我最初认为没有必要让这个函数成为静态成员函数。所以我删除它并且无法编译这个程序。没有其他原因。
  • @zenos 使它成为静态成员函数的原因是它可以是静态的。如果没有理由使它成为非静态的,那么它应该是静态的。为什么需要一个对象并在没有理由的情况下需要一个非常量对象?
  • @DavidSchwartz 你的意思是,所有函数成员都可以是静态的?对吧?我无法理解您的问题---“为什么需要一个对象并在没有理由要求的情况下需要一个非常量对象?” .可以举个例子吗?

标签: c++ static constants


【解决方案1】:

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

将“静态”添加到函数 cleanup_str。我无法理解为什么它可以通过。

静态方法不适用于实例,它只属于该类(它根本没有隐藏参数this)因此从const方法调用此类方法是安全的,不会破坏合同.如果您删除 static,那么该方法将变为常规 non const 方法,并且不再从 const 调用它是不安全的。

我尝试的另一种方法是:删除函数QueryResult的最后一个'const'关键字

现在您的方法query 变为非常量(this 的类型为TextQuery *),因此可以安全地从中调用非常量或静态方法。所以你的编译器错误消失了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 2012-04-11
    • 1970-01-01
    相关资源
    最近更新 更多