我正在尝试制作一个通用类型T的动态列表,其中重载了一些运算符以进行更好的操作。我还添加了一些成员功能,用于各种可访问性和排序。在函数findAll()中,我得到一个错误:
错误:将'
const List<int>
'作为'this'参数传递会丢弃限定符[-fpermission]">
在不同的头文件中进行了自定义异常处理。当未找到访问列表的元素或搜索超出列表大小时,它将返回一个异常。
struct outOfScope : public exception {
const char * what () const throw () {
return "Couldn't assign or retrieve value!, out of scope
issue!n";
}
};
我已经在函数findAll的末尾添加了constant关键字,仍然显示相同的错误。
template<class T>
class List //will not work for a list of arrays, and can't be made a typedef of fixed size
//"typedef List<vector> tensor(3)" will not work
//you will have to rather use List<List<vector>>
{
public:
T *p = NULL;
int s;//size
//public:
//constructor
List(){p=NULL; s=0;}
List(int i)
{
s = i;
if(p!=NULL)
{
delete [] p;
p = NULL;
}
p = new T [s];
if(!p)
{
throw pointerInitialization();
}
}
//copy constructor
List(const List<T>& l)
{
if(p!=NULL)
{
delete [] p;
p = NULL;
}
s = l.size();
s = l.size();
p = new T [s]; //Don't write in place of 'new T', p = l.p because
//it will store value without the need to use for loop but destructor 'delete [] p' will delete it multiple times,
//causing 'double delete error'
if(!p)
{
throw pointerInitialization();
}
for(int i=0; i<s; i++)
{
p[i] = l.p[i];
}
}
List(List<T>& l)
{
if(p!=NULL)
{
delete [] p;
p = NULL;
}
s = l.size();
s = l.size();
p = new T [s]; //Don't write in place of 'new T', p = l.p because
//it will store value without the need to use for loop but destructor 'delete [] p' will delete it multiple times,
//causing 'double delete error'
if(!p)
{
throw pointerInitialization();
}
for(int i=0; i<s; i++)
{
p[i] = l.p[i];
}
}
void operator=(const List<T>& l)
{
if(p!=NULL)
{
delete [] p;
p = NULL;
}
s = l.size();
p = new T [s];
if(!p)
{
throw pointerInitialization();
}
for(int i=0; i<s; i++)
{
p[i] = l.p[i];
}
}
void operator=(List<T>& l)
{
if(p!=NULL)
{
delete [] p;
p = NULL;
}
s = l.size();
p = new T [s];
if(!p)
{
throw pointerInitialization();
}
for(int i=0; i<s; i++)
{
p[i] = l.p[i];
}
}
//member functions
void setValues(int i);//can be used to reassign the variables any
T& operator[](int i)
{
if(i<s && i>=0)
return p[i];
else
{
throw outOfScope();
}
}
int size(){return s;}
void addAtEnd(T newEntry)//adding a node at the end of the list
{
s = s+1;
T* newP = new T[s];// new pointer of one greater size is created
newP[s-1] = newEntry;//at the last node, newEntry is added
for(int i=0; i<s-1; i++)//for the rest of the entry, *newP copies data of the *p
{
newP[i] = p[i];
}
delete [] p;//deleting the memory pointed by the pointer p, doesn't mean p has lost its existence
p = new T[s];//reassigning p to a new memory of size s(no need to use NULL before it as we are already
//reassigning it again. Also don't write T* p = new T[s], it will create a different p, because now the
//statement becomes a declaration type, there must not be two declarations of the same name p (once already
//declared in member variable declaration of class List
for(int i=0; i<s; i++)
{
p[i] = newP[i];
}
delete [] newP;
newP = NULL;
}
int find(T value); //takes argument as the element of list, returns the location of list (counting zero as first node)
List<int> findAll(T value) const//takes argument as the element of list, returns the location of list (counting zero as first node)
{
List<int> locList;
for(int i=0; i<s; i++)
{
if(p[i]==value)
{
locList.addAtEnd(i);
}
}
if(locList.size() != 0)
return locList;
else
{
throw outOfScope();
}
}
bool lookup(T value);
//destructor
~List()
{
delete [] p;//means whenever destructor is called to destroy the object,
//first of all, 'p' will delete the variable it is pointing to. Then the List obj will be destroyed
p = NULL;
// cout<<"ndestructror is called! n";
}
};
//--------------------------------------------------------------------------
//macros
#define forAll(List, i) for(int i=0; i<List.size(); i++)
实现代码:
#include<iostream>
#include<exception>
int main()
{
List<int> rollNo(5);
int k=0;
rollNo[k++] = 2;
rollNo[k++] = 2;
rollNo[k++] = 3;
rollNo[k++] = 2;
rollNo[k++] = 3;
List<int> findList = rollNo.findAll(rollNo[2]);
forAll(findList, i)
cout<<findList[i]<<endl;
return 0;
}
在行中:
List<int> findList = rollNo.findAll(rollNo[2]);
您正在调用List<int>
的复制构造函数,该构造函数采用const
引用:
List(const List<T>& l)
在这个构造函数中,您尝试访问l
:的大小
s = l.size();
但您不能,因为l
是const
限定的,而size()
不是,并且您只能对const
限定的变量调用const
限定的方法。
要解决此问题,您需要const
-符合size()
:
int size() const { return s; }
以下是一些针对您的代码的建议,请尝试查找最近的C++书籍以了解更多信息:
- 除非是练习,不要制作自己的
List
,使用std::vector
- 用CCD_ 14代替CCD_
- 不提供采用非常量左值引用的构造函数或赋值运算符(
List(List<T>&)
和operator=(List<T>&)
- 提供move构造函数和move赋值操作符(
List(List<T>&&)
和operator=(List<T>&&)
),见0/3/5规则 - 返回分配操作员的
List<T>&
- 检查分配运算符的复制和交换习惯用法
const
-限定应该是size()
、find()
、lookup()
的函数- 添加
const
——相关方法的合格过载:const T& operator[](int i) const
- 检查一些C++实用程序函数,如
copy
或equal_range