C++沉思录-第十二章-数组模板的问题

天外来客-007 2011-05-06 11:37:01


C++沉思录第十二章,给了一个数组模板,具体的代码如下:


template<class T> class Array
{
public:
explicit Array(): data(0), sz(0) {}
explicit Array(unsigned size)
:sz(size), data(new T[size]) {}
~Array()
{
if (NULL != data)
{
delete[] data;
data = NULL;
}
}

const T& operator[](unsigned n) const
{
if (n >= sz || data == 0)
{
throw "Array subscript out of range";
}

return data[n];
}

T& operator[](unsigned n)
{
if (n >= sz || data == 0)
{
throw "Array subscript out of range";
}

return data[n];
}

operator const T*() const
{
return data;
}

operator T*()
{
return data;
}

private:
T * data;
unsigned sz;
Array(const Array&);
Array& operator=(const Array&);
};


该模板在使用时有个缺陷,就是 operator[]和operator T*有冲突。
Operator T* 等类似的操作使得Array<T> 隐式转化为T* 成为可能,而在使用小标运算时,如下
Array<int> x(MAX_BUFFER);

int i = 0;
for (i = 0; i < MAX_BUFFER; ++i)
{
x[i] = i + 1;
}



在调用operator[]时,会把第一个参数隐式转化为T*,这个operator T*的定义形式相冲突。

解决办法,就是不定义operator[]。

有没有更好的解决方案?欢迎跟帖!
...全文
165 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
天外来客-007 2011-05-09
  • 打赏
  • 举报
回复
经验证,8楼的方案可行。
[Quote=引用 9 楼 lightlater 的回复:]
引用 8 楼 ri_aje 的回复:
改成这样就没冲突了。

C/C++ code

template<class T> class Array
{
public:
explicit Array(): data(0), sz(0) {}
explicit Array(unsigned size)
:sz(size), data(new T[size]) {}
~Array()……
[/Quote]
天外来客-007 2011-05-07
  • 打赏
  • 举报
回复
从Array设计的角度,我倾向于扔掉operator[],因为内置数组并不做越界检查,把越界的问题交个使用者,而隐式的类型转换则支持。
其实,当遇到有二义性的地方,应该使用明确的语义定义它,这样才能避免错误。
[Quote=引用 5 楼 qq120848369 的回复:]
operator* 扔掉,提供一个函数返回data.
[/Quote]
天外来客-007 2011-05-07
  • 打赏
  • 举报
回复
其实就是禁止隐式类型转换,不过有不少这样的建议,因为当容易产生二义性时,就要用明确地语义定义它![Quote=引用 5 楼 qq120848369 的回复:]
operator* 扔掉,提供一个函数返回data.
[/Quote]
ri_aje 2011-05-07
  • 打赏
  • 举报
回复
改成这样就没冲突了。

template<class T> class Array
{
public:
explicit Array(): data(0), sz(0) {}
explicit Array(unsigned size)
:sz(size), data(new T[size]) {}
~Array()
{
if (NULL != data)
{
delete[] data;
data = NULL;
}
}

template <typename index_t>
const T& operator[](index_t n) const
{
if (n >= sz || data == 0)
{
throw "Array subscript out of range";
}

return data[n];
}

template <typename index_t>
T& operator[](index_t n)
{
if (n >= sz || data == 0)
{
throw "Array subscript out of range";
}

return data[n];
}

operator const T*() const
{
return data;
}

operator T*()
{
return data;
}

private:
T * data;
unsigned sz;
Array(const Array&);
Array& operator=(const Array&);
};
天外来客-007 2011-05-07
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wuchengfeng222 的回复:]
楼主 这个书好么, 适合 那个阶段的学习~~ ?
[/Quote]
适合有一定经验的人士学习,不要上来就看的,除非你是天才,否则,是看不懂的!
wuchengfeng222 2011-05-07
  • 打赏
  • 举报
回复
楼主 这个书好么, 适合 那个阶段的学习~~ ?
天外来客-007 2011-05-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ri_aje 的回复:]
改成这样就没冲突了。

C/C++ code

template<class T> class Array
{
public:
explicit Array(): data(0), sz(0) {}
explicit Array(unsigned size)
:sz(size), data(new T[size]) {}
~Array()……
[/Quote]

可行!
ryfdizuo 2011-05-06
  • 打赏
  • 举报
回复
取舍一下吧。鱼熊掌。
天外来客-007 2011-05-06
  • 打赏
  • 举报
回复
其实禁止隐式类型转换是不错的选择,但是这样就不具有内置数组的特性了。
总之,要实现某些设想,总是要做出些取舍!内建数组也没有越界检查,不定义下表操作符,或许是比较合理的。
www_adintr_com 2011-05-06
  • 打赏
  • 举报
回复
不重载你怎么做下标越界检查?
这个是你使用的问题,把你的
int i = 0;
改成 unsigned int 就不冲突了.
bdmh 2011-05-06
  • 打赏
  • 举报
回复
嗯,的确是个问题,个人感觉,没必要重载的运算符还是不要重载了,特别是下标访问,真的有必要重载吗,或许这个例子就是为了说明运算符重载,而没有实际意义
qq120848369 2011-05-06
  • 打赏
  • 举报
回复
operator* 扔掉,提供一个函数返回data.

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧