pointer()
这些定义是相等的?从const成员函数返回类成员上的指针
class Example
{
public:
AnotherClass* const pointer() const;
AnotherClass* pointer() const;
private:
AnotherClass* m_pointer;
}
它保证我有人不能改变m_pointer指向的内存吗?
pointer()
这些定义是相等的?从const成员函数返回类成员上的指针
class Example
{
public:
AnotherClass* const pointer() const;
AnotherClass* pointer() const;
private:
AnotherClass* m_pointer;
}
它保证我有人不能改变m_pointer指向的内存吗?
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指向的对象。
是模拟此: int * const和 int const *? – Eugene
@Eugene对不起,我犯了一个错误。我现在更新了我的答案。希望现在更清楚。 –
您需要的第一种方法的返回类型是其中之一:
AnotherClass const * pointer() const;
或
const AnotherClass* pointer() const;
您所做的一切是常量指针返回到非const对象。
你想要的是一个非常量指针到一个常量对象。
此外,要遵循典型的做法,你的第二种方法不应该是const。
AnotherClass* pointer();
这里要考虑几件事情:
什么是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
在*
左侧。
一个非常深入的解释const,惊讶你从不提及从右到左的阅读顺序约定。 –
你想让成员变量'm_pointer'保持不变,还是指向的内存? –
指向的内存。谢谢,我没有问确切的问题。 – Eugene