c ++

时间:2015-06-26 13:23:42

标签: c++ list

list.h

class Link {
public:
    string value;
    Link(const string& v, Link* p = 0, Link * s = 0):
        value(v), prev(p), succ(s) {}
    Link* insert(Link* n);              // insert n before this object
    Link* add(Link* n);                 // insert n after this object
    Link* erase();                      // remove this object from list
    Link* find(const string& s);        // find s in list
    Link* const find(const string& s) const;                       
    Link* advance(int n) ;                // get the nth successor 

    Link* next() const { return succ; }
    Link* previous() const { return prev; }

private:
    Link* prev;
    Link* succ;
};

你能告诉我为什么我们需要两个版本的find()

Link* find(const string& s);        // find s in list
Link* const find(const string& s) const;    

在这个自制的双链表中,这两个版本之间的主要区别是什么?

3 个答案:

答案 0 :(得分:6)

您希望同一成员函数的const和非const版本的原因是您可以在const和非const对象上调用它们:

Link link = ...;
link.find("hello"); // calls non-const find(), returns Link*

const Link clink = ...;
clink.find("goodbye"); // calls find() const

虽然,您的const版本会返回Link* const。这是指向const的{​​{1}}指针。返回Link,指向const Link*

的指针会更有意义
const Link

通过这种方式,您的Link* find(const std::string& ); const Link* find(const std::string& ) const; const仍然可以找到条目 - 只是不修改它们。这将保持Link - ness。只要不修改它们,就可以在const集合中查找内容。

答案 1 :(得分:1)

从我从这两个函数声明中可以看出,你不需要两者。即使非const版本不存在,函数的const版本实际上也会涵盖所有可能的用例。

事实上,最好的声明可能是这样的:

Link* find(const string& s) const;

此行中的第一个const

Link* const find(const string& s) const;

只是意味着返回的指针不能被指定为指向其他东西;但是,由于返回的指针可以直接使用,也可以立即分配给某个变量,因此不需要第一个const

也许你正在寻找的是这个设置:

Link* find(const string& s);
const Link* find(const string& s) const;

const放在基本类型(链接)旁边而不是星号(这意味着它是一个指针),您现在提供的方法可以指向某个链接,该链接可以执行或不执行操作根据您调用的链接是否为const,您可以修改该链接。

答案 2 :(得分:1)

  

你能告诉我为什么我们需要两个版本的find()

是。请考虑以下代码:

const Link x{ "x" };
auto y = x.find("x");
// y will be a Link * const, meaning you cannot change the pointer 
// address (not interesting) but you can change the object at that address.

Link x{ "x" };
auto y = x.find("x");
// y will be a Link *, meaning you can change both the pointer address
// contained in y (not interesting) and the object at that address

可以在const实例(以及const引用和指向const实例的指针)上调用const版本。非const版本只能在非const实例上调用。

无论哪种方式,const版本的签名都是错误的:你应该返回一个指向const值的指针,而不是一个指向非const值的const指针。

也就是说,功能应该是:

Link const * const find(const string& s) const;   
//   ^^^^^   ^^^^^

Link const * find(const string& s) const;   
//   ^^^^^   

但不是:

Link * const find(const string& s) const;   
//     ^^^^^