条款29:避免传回内部数据的handles
程序1:
class String{
public:
String(const char* value);m
~String();
operator char*() const //将String转换为char*
{ return data; }
private:
char *data;
}
考虑以下行为:
const String B("Hello World"); //B是一个const object
char *str = B; //调用operator char* ,返回data指针
strcpy(str,"Hi Mom"); //对str的修改同时也改变了const对象B
此函数的败笔在于传回了一个handle(指针)。
程序1——解决办法1:
inline String::operator char*() const
{
char* copy = new char[strlen(data)+1];
strcpy(copy,data);
return copy;//返回一个副本
}
这种做法是安全的,但是效率不高,而且需要client自行delete copy指针。不然有潜在的内存泄漏问题。
程序1——解决办法2:
inline String::operator const char*() const
{ return data; }
传回const char*,一样不能更改。
程序2:
class String{
public:
...
char& operator[](int index) const
{ return data[index]; }
private:
char *data;
};
const String s = "I'm constant";
s[0] = 'x'; //修改了const的值,但是编译器没有察觉
因为operator[]系以by reference方式传回其结果,这意味着函数调用者将会获得内部资料的一个别名,而且对这个别名的修改就是对原const对象的改变。
程序3:(非const成员函数也要避免传回内部handles)
String someFamousAuthor()
{
switch (rand() % 3) {
case 0:
return "A";
case 1:
return &