C++代理类可以帮助我们实现想要得效果,例如:
1.多维数组
2.区分左值和右值(区分读和写)
3.压制隐式转换
多维数组
想要实现一个二维数组类,重载[][]肯定是不行的 ,无法通过编译,这时就可以通过代理类来实现:
class MyProxy
{
public:
MyProxy(char *s) :s(s) {}
char operator[](int index)
{
return s[index];
}
private:
char *s;
};
class MyString
{
public:
MyString(int row) :p(new char[row][100]) {}
MyProxy operator[](int index)
{
return p[index];
}
private:
char(*p)[100];
};
区分读和写
=左边为写,右边为读,但是如果重载[]并不能区分是读还是写,对于非常量对象,不管是读还是写,调用的都是非常量的重载的[]函数,这时候就要使用代理类,不直接返回字符,而是返回一个代理类对象,在代理类中重载=即可区分读和写。—more effective C++ 条款30
class WriteOrReadProxy
{
public:
WriteOrReadProxy(char *s, int index) :s(s), index(index) {}
void operator=(char c)
{
s[index] = c;
cout << "写" << endl;
//return *this;
}
void operator=(const WriteOrReadProxy& temp)
{
s[index] = temp.s[temp.index];
cout << "写" << endl;
}
char operator=(char c)const
{
cout << "读" << endl;
return s[index];
}
operator char()const
{
cout << "读" << endl;
return s[index];
}
operator char()
{
cout << "读" << endl;
return s[index];
}
private:
char *s;
int index;
};
class WriteOrRead
{
public:
WriteOrRead(char *s) :s(s) {}
/*char& operator[](int index)
{
return s[index];
}
const char& operator[](int index)const
{
return s[index];
}*/
WriteOrReadProxy operator[](int index)
{
return WriteOrReadProxy(s, index);
}
const WriteOrReadProxy operator[](int index) const
{
return WriteOrReadProxy(s, index);
}
private:
char *s;
};
int main()
{
WriteOrRead s(new char[10]);
s[3] = 'a';
cout << s[3] << endl;
s[4] = 'b';
cout << s[4] << endl;
s[3] = s[4];
cout << s[3] << endl;
return 0;
}
压制隐式转换
class MyArraySize
{
public:
MyArraySize(int size) :theSize(size) {}
int size()const { return theSize; }
private:
int theSize;
};
class MyArray
{
public:
//MyArray(int size) :size(size),data(new int[size]) {}
MyArray(MyArraySize size) :size(size.size()), data(new int[size.size()]) {}
int operator[](int index)
{
return data[index];
}
bool operator==(const MyArray &temp)
{
return data == temp.data;
}
private:
int *data;
int size;
};
int main()
{
MyArray arr(10);
MyArray arr2(10);
for (int i = 0; i < 10; i++)
{
if (arr == arr2[i]) //不使用代理类会通过编译
{
cout << "==" << endl;
}
}
return 0;
}
使用MyArray(int size) 构造函数会将int类型隐式转换为MyArray类型从而通过编译,如果将构造函数中的int类型换成代理类的话则不存在隐式转换。explict关键字也可以解决这个问题,对于不支持explict的则可以使用代理类来解决。—more effective C++条款5