【问题标题】:Can const member function return a non-const pointer to a data member?const 成员函数可以返回指向数据成员的非常量指针吗?
【发布时间】:2012-01-09 13:05:53
【问题描述】:

代码先行:

class A
{
    public:
        ...
        int *foo() const
        {
            return _px;
        }
    private:
        int *_px;
}

成员函数foo返回一个指向private成员_px的非常量指针,我认为这为修改成员_px打开了大门,对吧?

fooconst 成员函数吗?我应该在返回类型前添加const 吗?

更新

const-member-function 应该保证的是,它不能改变任何数据成员,对吧?

在我的情况下,函数foo 不会打开修改class As 数据成员_px 的大门,而是打开修改_px 指向的大门,所以我的问题是,这是否违反const 函数应该保证什么?

【问题讨论】:

  • 启用警告时编译器会说什么?
  • @ArunMu gcc 4.6.1 什么也没说。
  • @ArunMu,好吧,看起来没什么。
  • const 遗憾的是不能跨引用/指针传递。
  • 它是否违反任何东西取决于类的目的、指针和函数。从技术上讲是可以的。

标签: c++ constants


【解决方案1】:

const 成员函数只能返回 const 指针或对成员的引用。

但是,您的示例没有返回指向成员的指针;它正在返回恰好是指针的成员的副本。这在 const 成员函数中是允许的(即使指针恰好指向另一个成员)。

这是不允许的(注意它现在返回一个引用):

int *& foo() const {return _px;}

但这会(返回const 引用):

int * const & foo() const {return _px;}

【讨论】:

  • 先生,您的解释非常清楚和正确。 IMO,fooclass A 中打开了修改_px 指向的内容的大门,我认为这使得foo 成为非常量成员函数,对吧?
  • @Alcott: const 在成员函数上只保护对象本身的成员,而不是任何进一步的间接级别。所以在函数_px 内实际上是int * const;指针本身不能修改,但它的目标可以。
  • 其实你可以const成员函数返回一个非const引用,像这样:struct O { int* a; int& getA() const { return *a; }
【解决方案2】:

int *_px 在 const 成员函数内变为 int *const _px,这意味着指针无法重新定位,但指向的数据仍然可以修改。此外,您的函数会返回指针的副本,因此无论如何都没关系。

【讨论】:

    【解决方案3】:

    它不会打开修改_px 的大门,而是打开_px 指向的大门。由您决定是否允许这样做。

    例如,iterator::operator-> 将返回一个非 const 指针,const_iterator::operator-> 将返回一个 const 指针。两种方法本身都可以是 const。

    【讨论】:

      【解决方案4】:

      是的,对于您的情况,它可以。但是,通常建议不要这样做,因为它允许更改常量对象:

      void f(const A& a) 
      {
        *(a.foo()) = 42; // damn!
      }
      

      【讨论】:

        【解决方案5】:

        是的,例如查看 std::streambuf 指针:

        protected:
           char* pbase() const;
           char* pptr() const;
           char* epptr() const;
        

        http://en.cppreference.com/w/cpp/io/basic_streambuf/pptr

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-18
        • 2016-08-17
        • 1970-01-01
        • 2011-09-19
        • 2011-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多