如果将成员指针取消引用到非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;
};
答案 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
};
只有最后一个方法会返回错误,因为:
答案 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
};