在表达式计算时可能会存在隐式转换,如下
template <typename T>
class Array
{
public:
Array(int size);
T& operator[](int index);
T operator[](int index) const;
private:
//...
};
Array<int> a(10);
Array<int> b(10);
// if(a == b[1])
// a == static_cast<Array<int>>(b[1])
// oooops...
上述代码中if(a == b[i])可通过编译且可正常执行,但不是我们期望的。
其原因是Array(int)
构造函数隐式转换。
如何避免?
为避免隐式转换,可将构造函数设置为explicit
template <typename T>
class Array
{
public:
explicit Array(int size);
T& operator[](int index);
T operator[](int index) const;
private:
//...
};
Array<int> a(10);
Array<int> b(10);
// if(a == b[1])
// complie error
若编译器不支持explicit
声明,可以采取另一种方式:不允许直接传入int size
进行构造:
template <typename T>
class Array
{
public:
class ArraySize
{
public:
ArraySize(int size):size_(size){}
int size() const {return size_;}
private:
int size_;
};
explicit Array(ArraySize size);
T& operator[](int index);
T operator[](int index) const;
private:
//...
};
Array<int> a(10);
// Array<int>.ctor( ArraySize(10) )
Array<int> b(10);
// if(a == b[1])
// complie error
不允许从int
默认构造Array<int>
,因为这需要二重转换:从int
到ArraySize
,然后根据ArraySize
构造Array<int>
。
这里的ArraySize
被称为proxy class,因为它是为了其他对象而存在的。
Proxy object以超越外观的形式控制软件的行为。