0

我已经调试了近6个小时,现在我即将放弃。 是的,这只是一个学校项目。但我已经打开了我的副本,现在我只想知道它为什么不起作用。怎么只有一行告诉我operator =不可行?但其他人很好?

在我的smartPointer类中,我想重载operator =。对我来说这似乎很好,应该很好去。但是,不,我的初始化器列表构造函数中的一行代码导致编译器错误。我标记为“问题在这里!!”。我没有看到它与其他构造函数中的相同行不同。如果我评论它,它会编译。但显然它会由于未分配内存而导致运行时错误。有什么我忽略了吗?请给我一些提示。哦,我知道我的代码有潜在的删除问题,例如同一个地址会被删除多次,但我想继续自行调试它。我只想知道为什么只有那个特定的行导致问题,因为该行存在于其他构造函数中,但都很好。非常感激。

#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

请提供[MCVE] –

+0

我仔细检查了,但我不知道如何最大限度地减少这个。这两个类和主要功能都被使用。每个构造函数也被使用。我摆脱了一些没有使用的功能。感谢您的建议。 –

回答

0

我认为你的代码的问题是operator =的定义。我的建议是阅读this:这里有一些原因,你应该声明你的赋值运算符为const或者使用move assignment来改变定义。无论如何,我找到了另一种方法来轻松实现智能指针:Implementing a simple smart pointer in C++。正如你在那里看到的那样,它使用了一个特定的类来计算对分配对象的引用。

(你为什么不使用nullptr,而不是分配0到原始指针?)

0

两个问题我看到::

  1. psmartPointer<T>类型的对象。它在堆栈上创建。不要删除!!你正在删除它在重载的功能中分配
  2. SA的缺省构造函数不正确。 用smartPointer<T>(nullptr)初始化p。我会建议使用初始化列表构造函数。

除此之外,您的智能指针是不够聪明: 参考https://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c

快乐学习:)

+0

谢谢,你是对的,p不应该被删除。对于2,我已经有了一个initializer_list构造函数,这不够吗? –

+0

那么,你不需要一个默认的构造函数,直到你使用它。关键是你已经设置了'p = NULL'。由于它是一个对象(而不是指针),因此该语句不正确。 –

+0

你能解决你的问题队友吗? –

相关问题