对动态内存进行操作,重写一个const成员函数有意义吗?

Posted

技术标签:

【中文标题】对动态内存进行操作,重写一个const成员函数有意义吗?【英文标题】:Operating on dynamic memory, is it meaningful to overload a const memeber function? 【发布时间】:2014-01-10 14:07:57 【问题描述】:

C++ Primer 5 Edition 中的一个练习让我卡住了,就像

练习 12.3:这个类是否需要 const 版本的 push_backpop_back?如果是这样,请添加它们。如果没有,为什么不需要它们? (第 458 页)

下面是课程。为简化代码,省略了成员frontback 的定义。

class StrBlob 

public:
    typedef std::vector<std::string>::size_type size_type;
    StrBlob();
    StrBlob(std::initializer_list<std::string> il);
    size_type size() const  return data->size(); 
    bool empty() const  return data->empty(); 
    // add and remove elements
    void push_back(const std::string &t) data->push_back(t);
    void pop_back();
    // element access
    std::string& front();
    std::string& back();
private:
    std::shared_ptr<std::vector<std::string>> data;
    // throws msg if data[i] isn't valid
    void check(size_type i, const std::string &msg) const;
;

StrBlob::StrBlob(): data(make_shared<vector<string>>())  
StrBlob::StrBlob(initializer_list<string> il):
          data(make_shared<vector<string>>(il))  

void StrBlob::check(size_type i, const string &msg) const

    if (i >= data->size())
        throw out_of_range(msg);


void StrBlob::pop_back()

    check(0, "pop_back on empty StrBlob");
    data->pop_back();

我试图重载一个 const 成员 void StrBlob::pop_back() const,如下所示。

void StrBlob::pop_back() const

    check(0, "pop_back on empty wy_StrBlob");
    data->pop_back();

编译器没有抱怨这个 const 成员。想知道我做得对吗?有没有可能调用这个 const 成员?添加这个 const 成员有意义吗?为什么?

【问题讨论】:

您可以通过not 添加const 成员函数,然后声明const StrBlob 对象,最后尝试调用push_back() 和/或@ 来检验您的假设987654329@就可以了。如果您遇到编译器错误,那么您确实需要相关成员函数的 const 版本。 在这种情况下编译器不会报错,因为data 是一个指针(语义上),所以指针语义适用:some_type* constsome_type const* 不同。 this-&gt;dataconst 成员函数中的“类型”是shared_ptr&lt;vector&lt;string&gt;&gt;&gt; const,而不是shared_ptr&lt;vector&lt;string&gt; const&gt; 【参考方案1】:

如果你愿意,你当然可以这样做,但似乎没有任何合乎逻辑的理由。编译器不会抱怨,因为这不会修改 data(它是一个指针),而是修改 data 指向的东西,这对于 const 指针是完全合法的。

【讨论】:

const 重载不会破坏 const 成员函数的约定,不会修改对象的可观察状态(size()empty())吗? @DyP 绝对。这就是为什么似乎没有任何合乎逻辑的理由这样做。 啊,你把它藏在那里了;)我以为你指的是void pop_back()void pop_back() const具有相同的“功能”(而不是iter begin()const_iter begin() const) . @DavidSchwartz 我可以这样总结一下吗:void pop_back()void pop_back() const 提供了不同的功能,但是添加后一个没有什么逻辑意义? @Alan.W 没错。这只是一种让const 在课堂上表现不合逻辑的方法。

以上是关于对动态内存进行操作,重写一个const成员函数有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章

第十二章 类和动态内存分配

const函数

如何复制动态分配的对象(具有一个类的 const 成员)

如何在 const 成员函数中使用非常量成员函数?

类的默认成员函数

如何编写一个返回对成员对象的引用的 const 访问器,以便可以对其进行编辑?