- const A a;是否会变化?答案取决于其成员函数的组成结构。
- 先看一个String类:
class String
{
public:
String(const char *value);
~String();
operator char *() const; //转换String到char *
private:
char *data;
};
const String B(“Hello World”);
char *str = B; //调用B.operator char*();
strcpy(str, “Hello Mom”);
B的值是否会改变,完全取决于String::operator char *的实现。
- 先看一个错误的实现:
inline String::operator char *() const
{ return data;}
- 这个函数返回了一个句柄(指针),而这个句柄所指向的信息本来应该是隐藏在被调用函数所在的String对象的内部,这个句柄就给了调用者自由访问data所指向的私有数据的机会。
- 显然任何对str所指向的内存的修改都会使得B的有效值发生变化。
- String::operator char *本身写的没有一点错,但是它可以用于const对象。如果这个函数不声明为const,就不会有问题,因为这样它就不能用于像B这样的const对象了。但是将String对象转换为相应的char *形式是很合理的事情,所以,还是应将函数保持为const。
- 一个执行很慢但很安全的函数
inline String::operator char *() const
{
char *copy = new char[strlen(data) +1];
strcpy(copy, data);
return copy;
}
这个函数运行起来更慢;此外,函数的调用者还要记得delete掉返回的指针。
- 使函数返回一个指向const char的指针:
class String
{
public:
operator const char *() const;
};
inline Stirng::operator const char *() const
{ return data; }
这个函数既快又安全。可以满足大多数程序的需求。
- 应该要注意,引用也是返回内部数据的一个途径。
- 对于const成员函数来说,返回句柄是不明智的,因为它会破坏数据抽象。对于非const成员函数来说,返回句柄会带来麻烦,特别是涉及到临时对象时。句柄就像指针一样,可以是悬浮的。
- 不能对本条款绝对化。想消灭所有的悬浮指针(句柄)是不现实的,只要不是万不得已,就要避免返回句柄。