在表达式计算时可能会存在隐式转换,如下
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以超越外观的形式控制软件的行为。
本文探讨了在C++编程中隐式类型转换可能导致的问题,特别是在模板类如Array的上下文中。通过示例展示了当Array的构造函数没有被声明为explicit时,可能导致意外的比较操作。解决方案是使用explicit关键字来禁止这种隐式转换,从而增强代码的清晰性和安全性。如果编译器不支持explicit,文章提出了一种使用代理类(proxy class)ArraySize的替代方法,以防止不需要的构造过程。
1111

被折叠的 条评论
为什么被折叠?



