2013-11-20 233 views
0

pointer()这些定义是相等的?从const成员函数返回类成员上的指针

class Example 
{ 
public: 
    AnotherClass* const pointer() const; 
    AnotherClass* pointer() const; 


private: 
    AnotherClass* m_pointer; 
} 

它保证我有人不能改变m_pointer指向的内存吗?

+1

你想让成员变量'm_pointer'保持不变,还是指向的内存? –

+0

指向的内存。谢谢,我没有问确切的问题。 – Eugene

回答

1

pointer的两个重载仅在返回类型上有所不同。你的C++编译器不会接受,这是一个错误。

假设指针()只返回m_pointer:

声明AnotherClass* pointer() const;将暴露m_pointer的值。该类的用户将无法更改m_pointer,但可以更改m_pointer指向的对象。

声明AnotherClass* const pointer() const;AnotherClass* pointer() const;非常相似,但返回的值(临时指针)为const。这个声明没有意义,因为你已经不能在第一个声明中改变返回值。在任何情况下都不能写example.pointer() = nullptr。并且,如果将返回值分配给像p = example.pointer()这样的变量,则指针()的返回值是否为常量也没有区别。

声明const AnotherClass* pointer() const;AnotherClass const * pointer() const;会暴露m_pointer的值。该类的用户将无法更改m_pointer,并且他们将无法更改m_pointer指向的对象。

+0

是模拟此: int * const和 int const *? – Eugene

+0

@Eugene对不起,我犯了一个错误。我现在更新了我的答案。希望现在更清楚。 –

2

您需要的第一种方法的返回类型是其中之一:

AnotherClass const * pointer() const; 

const AnotherClass* pointer() const; 

您所做的一切是常量指针返回到非const对象

你想要的是一个非常量指针到一个常量对象

此外,要遵循典型的做法,你的第二种方法不应该是const。

AnotherClass* pointer(); 
1

这里要考虑几件事情:

什么是const:指针或指针对象?

让我们看看这些不同的声明之间的差异。

int x, y; 

int  *  p = &x; // 0 
const int *  p = &x; // 1 
int const *  p = &x; // 2 
int  * const p = &x; // 3 
const int * const p = &x; // 4 
int const * const p = &x; // 5 

(0)表示p可以改变(p = &y;是OK)以及它指向(x)可以通过p改变(*p = y;是OK)。

(1)和(2)是等价的,并意味着p可以改变(p = &y;是OK)以及它指向(x)不能通过p改变(*p = y;是错误的)。

(3)意味着p不能改变(p = &y;是误差),并将其指向(x)什么是可以改变经由p*p = y;是OK)

(4)和(5)是等效的,并意味着p无法更改(p = &y;是错误),它指向的内容(x)不能通过p更改(*p = y;是错误)。

一个简单的方法来记住这是在看*,认为它分离的对象常量性,就是

(一)const之前*(如const int * [...]int const * [...])是指尖锐的物体(类型int)是const;和

(b)一种const*(例如[...] * const p [...];)意味着指示器是const,并且不能被改变。

如果函数返回const对象会发生什么?

考虑:

class some_class; 

const some_class a(); // equivalent to 'some_class const a();' 
     someclass b(); 

const int  c(); // equivalent to 'int const c();' 
     int  d(); 

然后,(假设some_class具有可访问的赋值运算符),我们有:

some_class x; 

a() = x; // illegal : the returned object is const 
b() = x; // OK  : the returned object is not const 

是很自然的认为,c()d()行为相同,但这是案例:

c() = 0; // illegal 
d() = 0; // also illegal!!! 

原因是,如果函数返回基本类型(例如, int,bool,char,任何指针类型,...),那么返回的对象不能被分配给。因此, 返回一个const基本类型的对象的行为与返回非常量的对象相同

怎么样在返回类型上重载?

考虑

int f(); // first overload. 
double f(); // second overload. 

这是非法的。我们不能只在返回类型上重载。一个原因是我们总是可以忽略函数返回的对象。例如,如果允许在返回类型上重载,那么将在下面调用哪个超载f

int main() { 
    f(); // which f? 
    return 0; 
} 

回答这个问题...

考虑第一个声明

AnotherClass* const pointer() const; 

从我们所看到的,这意味着pointer()返回AnotherClass*类型的const对象(指针类型)。由于指针类型是一个基本的类型,功能pointer上述行为相同,如果它是声明为

AnotherClass* pointer() const; 

这是第二过载。这是为什么有这两个重载没有意义的第一个原因。但与后面的相比,这只是一个薄弱的原因。

当我说“行为相同”时,我并不是指“等效”。两种重载的返回类型是不同的。正如我们所看到的,我们不能仅仅在返回类型上重载。这是非法的,代码不能编译。

它保证我有人不能改变m_pointer指向的内存吗?

不,再次,无论重载行为相同,并返回一个指针,可以通过该指针被改变的对象。你想要的是这样的:

const AnotherClass* pointer() const { return m_pointer; } 
// or 
// AnotherClass const* pointer() const { return m_pointer; } 

通知的const*左侧。

+0

一个非常深入的解释const,惊讶你从不提及从右到左的阅读顺序约定。 –