我现在已经调试了近6个小时,我即将放弃。 是的,它只是一个学校项目。但我已经提交了我的副本,现在我只是想知道它为什么不起作用。
在我的smartPointer类中,我想重载operator =。这对我来说似乎很好,应该很好。但不,我的初始化列表构造函数中的一行代码导致编译器错误。我用&#34来标记它;问题在这里!!"。我不认为它与其他构造函数中的相同行有任何不同。如果我发表评论,它将编译。但显然它会因内存未分配而导致运行时错误。有什么我忽略的吗?请给我一些提示。哦,我知道我的代码有潜在的删除问题,以至于同一地址被多次删除,但我想继续自己调试。我只是想知道为什么只有那条特定的行引起问题,因为该行存在于其他构造函数中,但都很好。非常感谢。
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <initializer_list>
using namespace std;
//--------------------------------------------------------
//smart pointer class;
template <typename T>
class smartPointer{
private:
T* pointee; //raw pointer;
public:
smartPointer(T* raw = 0):pointee(raw){}
smartPointer(smartPointer<T>& rhs){
pointee = rhs.pointee;
rhs.pointee = 0;
}
//destructor;
~smartPointer(){
if(pointee !=0) delete [] pointee;
}
smartPointer<T>& operator=(smartPointer<T>& rhs){
if(this == &rhs) return *this;
delete pointee;
pointee = rhs.pointee;
rhs.pointee = 0;
return *this;
}
T* operator->() const{
return pointee;
}
T& operator*() const{
return *pointee;
}
T& operator[](int i) const{
return pointee[i];
}
};
//smart pointer class;
//--------------------------------------------------------
template <typename T>
class SA{
private:
int low, high;
smartPointer<T> p;
public:
//default constructor
//allows for writing things like SA a;
SA(){low=0; high=-1;p=NULL;}
//2 parameter constructor lets us write
//SA x(10,20);
SA(int l, int h){
if((h-l+1) <= 0){
cout<<"constructor error in bounds definition"<<endl;
exit(1);
}
low=l;
high=h;
p=smartPointer<T>(new T[h-l+1]);
}
//----------------------------------------------------------------------------
//new code added below!!!!!!!!!
//initializer list constructor;
SA(initializer_list<T> l){
int size = l.size();
low=0; high=size-1;
p=smartPointer<T>(new T[size]); //Problem here!!!
initializer_list<int>::iterator itr;
itr=l.begin();
for (int i=0; i<size; i++){
p[i]= *itr;
itr++;
}
}
//----------------------------------------------------------------------------
//new code above!!!!!!!!!
//single parameter constructor lets us
//create a SA almost like a "standard" one by writing
//SA x(10); and getting an array x index from 0 to 9
SA(int i){low=0; high=i-1;
p=smartPointer<T>(new T[i]);
}
//copy constructor for pass by value and
//initialization
SA(const SA& s){
int size=s.high-s.low+1;
p=smartPointer<T>(new T[size]);
for(int i=0; i<size; i++){
p[i]=s.p[i];
}
low=s.low;
high=s.high;
}
//destructor
// ~SA(){}
int getHigh(){
return high;
}
int getLow(){
return low;
}
//overloaded[] lets us write
//SA x(10,20); x[15]=100;
T& operator[](int i){
if(i<low || i>high){
cout<<"index "<<i<<" out of range"<<endl;
exit(1);
}
return p[i-low];
}
//overloaded assignment lets us assign
//one SA to another
SA& operator=(const SA& s){
if(this==&s) return *this;
delete[] p;
int size=s.high-s.low+1;
p=smartPointer<T>(new T[size]);
for(int i=0; i<size; i++)
p[i]=s.p[i];
low=s.low;
high=s.high;
return *this;
}
//overloads << so we can directly print SAs
friend ostream& operator<<(ostream& os, const SA<T>& s){
int size=s.high-s.low+1;
for(int i=0; i<size; i++)
os<<s.p[i]<<" ";
return os;
}
};
int main(){
SA<int> z{10,20,30};
cout<<"printing result for SA z {10,20,30};"<<endl;
cout<<z<<endl;
cout<<"SA z(1,3){10,20,30}; would not work because" <<endl;
cout<<"both (1,3) {10,20,30} are parameters where the latter"<<endl;
cout<<"one is a initializer_list. In addition, {} are used for"<<endl;
cout<<" initialization not assignment. But this would work:"<<endl;
cout<<"SA<int> x({5,6,7});"<<endl;
SA<int> x({5,6,7});
cout<<x<<endl;
// SA<int> v(1,3){1,2,3};
return 0;
}
答案 0 :(得分:0)
我认为代码的问题是operator =
的定义。我给你的建议是阅读this:这里有你为什么要将你的赋值运算符声明为const
或者使用move assignment
更改定义的原因。无论如何,我找到了另一种轻松实现智能指针的方法:Implementing a simple smart pointer in C++。正如你在那里看到的那样,它使用了一个特定的类来计算对分配的对象的引用。
(为什么不使用nullptr
而不是将0分配给原始指针?)
答案 1 :(得分:0)
我看到两个问题::
p
是smartPointer<T>
类型的对象。它是在堆栈上创建的。不要删除!!您正在重载的作业中将其删除p
初始化smartPointer<T>(nullptr)
。我建议使用构造函数的初始化列表。除此之外,您的智能指针还不够智能: 请参阅https://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c
快乐学习:)