C ++ - 为什么const函数不强制成员指针的常量?

时间:2012-04-03 13:13:33

标签: c++

如果将成员指针取消引用到非const引用中,则const函数似乎并不在意。也可以返回非const成员指针。但是,不允许返回具有值类型的数据成员的引用或地址。

为什么?

class Class
{
public:
unsigned int& value2(void) const
{
    *m_ptr = 10;
    return *m_ptr; 
    //Why?
}

unsigned int* value3(void) const
{
    return m_ptr; //Why?
}

private:
unsigned int* m_ptr;
};

5 个答案:

答案 0 :(得分:4)

编辑:

关于你的代码:你实际上从未改变成员或返回对它的引用。

unsigned int& value2(void) const
{
    *m_ptr = 10;
    return *m_ptr; 
                //Why?
}
//returns the value your member points to, not your member

unsigned int* value3(void) const
{
    return m_ptr; //Why?
}
//returns a copy of your member

不允许的是我在我的代码段中发布的版本。

例如:

struct A
{
   int * x;
   int& getX() const { return *x; }
   int* getX1() const { return x; }
   int*& getX2() const { return x; } //error here
};

只有最后一个方法会返回错误,因为:

  • 第一个返回值,这不是const。指针是常量。
  • 第二个返回指针按值,再次确定
  • 第三个实际上通过引用返回成员,这就是为什么它是非法的

答案 1 :(得分:2)

它确实强制成员指针的常量;只是不是指针指向的常量!

为了证明,以下是非法的:

class foo
{
public:
    void bar() const
    {
        p = 0;
    }

private:
    int* p;
};

会给您一个编译错误,例如assignment of member 'foo::p' in read-only object

基本上在const成员函数中,T类型的成员变量被视为T const,如果T是指针类型,那么就说int*,这会产生{ {1}},表示“const指向int的指针”,即指针不可修改,但取消引用它会产生int* const,而不是int&。如果const int&被视为T*T const *,那么这将是一个不同的故事。

至于基本原理,仅仅因为指针是对象状态的一部分,并不意味着指针指向的对象是(虽然它可以)。更改指针指向的内容不会更改对象的可设想状态

答案 2 :(得分:1)

我不认为我理解你的问题。我尝试了以下方法:

class X {
  int x;
  int* foo() const {
    return &x;
  }
};

int main() {
}

它正确地无法使用消息进行编译"错误:从'const int *'到'int *'和#34;的无效转换。

您的问题是否符合上述示例?如果不同,你能给出一个示例代码吗?


鉴于你现在对你的问题有更详细的解释,我理解你。 成员指针unsigned int* m_ptr在const-member-function中是常量。但是指针指向的内容---不是。该内容超出了对象的范围,const函数与它无关。

value2功能中,您无法更改指针本身。这就是全部。

答案 3 :(得分:1)

我认为这是困扰你的。

struct Example
{
   int * p;
   Example(): i(new int) {}
   ~Example() { delete p; }
};

const Example e;
*(e.i) = 7 

这没关系,因为指针没有改变,它仍然指向内存中的相同位置。

然而,这不好,因为它改变了指针:

e.i = new int(4);

如果你想要禁止这两个,你应该提供一个访问者功能。

class Example
{
  public:
    int * i() { return i_; }
    const int * i() const { return i_; }
  protected: 
    int i_;
};

现在我们有:

Example e1;
*( e.i() )=7; //OK

const Example e2;
*( e.i() )=7; // FAILS TO COMPILE.

答案 4 :(得分:0)

Const函数确实尊重其成员变量的常量。当您返回一个指向函数的指针时,您返回一个指针,您将返回该指针的副本,这是正常的,原因与您可以在const方法中返回对象的副本相同。但是,指针指向的内容不会被视为const,因此即使在const函数中也可以修改它。

例如:

    struct A
    {
        int n;
        int * p;
        int & f1() const {return n;} //not allowed
        int f2() const {return n;} //allowed
        int * f3() const {return p;} //allowed
        int *& f4() const {return p;} //not allowed
        int & f5() const {return *p;} //allowed, because what p points to is not const
    };