类模板编译报错 以及 函数未声明返回值,但有返回值的问题

C++语言 码拜 10年前 (2015-05-11) 1513次浏览 0个评论

问题1:编译报错 invalid use of template-name “”Array”” without an argument list
在类外实现的函数:Array &Array<T>::operator = (const Array & rhs) 报了这个错误,请教为什么错误?

问题2:函数未声明返回值,但有返回值。
Array<T>::operator T * ()
Array<T>::operator const T * () const 
这2个在类外实现的重载都没有说明返回值,但却有return,编译还没指出这2个函数有问题,请教为什么?

代码来自书本,我修改了下,模板代码如下:

#include <cassert>

//数组类模板定义
template <class T>
class Array {
private:
	T* list;	//T类型指针,用于存放动态分配的数组内存首地址
	int size;	//数组大小(元素个数)
public:
	Array(int sz = 50);			//构造函数
	Array(const Array<T> &a);	//拷贝构造函数
	~Array();	//析构函数
	Array & operator = (const Array &rhs); //重载"="使数组对象可以整体赋值
	T & operator [] (int i);	//重载"[]",使Array对象可以起到C++普通数组的作用
	const T & operator [] (int i) const;	//"[]"运算符的const版本
	operator T * ();	//重载到T*类型的转换,使Array对象可以起到C++普通数组的作用
	operator const T * () const;	//到T*类型转换操作符的const版本
	int getSize() const;	//取数组的大小
	void resize(int sz);	//修改数组的大小
};

//构造函数
template <class T>
Array<T>::Array(int sz) {
	assert(sz >= 0);	//sz为数组大小(元素个数),应当非负
	size = sz;	// 将元素个数赋值给变量size
	list = new T [size];	//动态分配size个T类型的元素空间
}

//析构函数
template <class T>
Array<T>::~Array() {
	delete [] list;
}

//拷贝构造函数
template <class T>
Array<T>::Array(const Array &a) {
	//从对象x取得数组大小,并赋值给当前对象的成员
	size = a.size;
	//为对象申请内存并进行出错检查
	list = new T[size];	// 动态分配n个T类型的元素空间
	//从对象X复制数组元素到本对象
	for (int i = 0; i < size; i++)
		list[i] = a.list[i];
}

//重载"="运算符,将对象rhs赋值给本对象。实现对象之间的整体赋值
/*
Array & operator = (const Array &rhs); //类模板的声明原型
*/
template <class T>
Array &Array<T>::operator = (const Array & rhs) {
	if (&rhs != this) {
		//如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配
		if (size != rhs.size) {
			delete [] list;		//删除数组原有内存
			size = rhs.size;	//设置本对象的数组大小
			list = new T[size];	//重新分配n个元素的内存
		}
		//从对象X复制数组元素到本对象
		for (int i = 0; i < size; i++)
			list[i] = rhs.list[i];
	}
	return *this;	//返回当前对象的引用
}

//重载下标运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能
template <class T>
T &Array<T>::operator[] (int n) {
	assert(n >= 0 && n < size);	//检查下标是否越界
	return list[n];			//返回下标为n的数组元素
}

template <class T>
const T &Array<T>::operator[] (int n) const {
	assert(n >= 0 && n < size);	//检查下标是否越界
	return list[n];			//返回下标为n的数组元素
}

//重载指针转换运算符,将Array类的对象名转换为T类型的指针,
//指向当前对象中的私有数组。
//因而可以象使用普通数组首地址一样使用Array类的对象名
template <class T>
Array<T>::operator T * () {
	return list;	//返回当前对象中私有数组的首地址
}

template <class T>
Array<T>::operator const T * () const {
	return list;	//返回当前对象中私有数组的首地址
}

//取当前数组的大小
template <class T>
int Array<T>::getSize() const {
	return size;
}

// 将数组大小修改为sz
template <class T>
void Array<T>::resize(int sz) {
	assert(sz >= 0);	//检查sz是否非负
	if (sz == size)	//如果指定的大小与原有大小一样,什么也不做
		return;
	T* newList = new T [sz];	//申请新的数组内存
	int n = (sz < size) ? sz : size;	//将sz与size中较小的一个赋值给n
	//将原有数组中前n个元素复制到新数组中
	for (int i = 0; i < n; i++)
		newList[i] = list[i];
	delete[] list;		//删除原数组
	list = newList;	// 使list指向新数组
	size = sz;	//更新size
}

1.

Array<T> &Array<T>::operator

2.因为转换的结果必然是声明的类型,不需要画蛇添足

引用 1 楼 iyomumx 的回复:

1.

Array<T> &Array<T>::operator

2.因为转换的结果必然是声明的类型,不需要画蛇添足

无比感谢,请问第一个为什么要加个参数列表<T>呢?

引用 1 楼 iyomumx 的回复:

1.

Array<T> &Array<T>::operator

2.因为转换的结果必然是声明的类型,不需要画蛇添足

对于第二个我还是有点疑问,不声明返回类型,却返回一个值不会导致异常吗?就像声明了返回类型,但是没有返回值那样?

40分

template<typename T>
class Array { /* .. */ } 
里面,Array就默认为Array<T>,而你的实现写在类外,所以必须加上模板参数

转换运算符的名字就是它的返回类型,设计上就不再要求写返回类型了
operator T * ()  返回T*
operator const T * () 返回const T*

引用 4 楼 iyomumx 的回复:


template<typename T>
class Array { /* .. */ } 
里面,Array就默认为Array<T>,而你的实现写在类外,所以必须加上模板参数

转换运算符的名字就是它的返回类型,设计上就不再要求写返回类型了
operator T * ()  返回T*
operator const T * () 返回const T*

明白了,太感谢你了。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明类模板编译报错 以及 函数未声明返回值,但有返回值的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!