为什么只有一行告诉我operator=不可行?但其他人都还好?

问题描述 投票:0回答:2

我已经调试了近 6 个小时了,我快要放弃了。 是的,这只是一个学校项目。但我已经上交了我的副本,现在我只想知道为什么它不起作用。

在我的 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;
}
c++ memory-management operator-overloading smart-pointers initializer-list
2个回答
0
投票

我认为您的代码的问题在于

operator =
的定义。我给你的建议是阅读this:这里有你应该将赋值运算符声明为
const
或使用
move assignment
更改定义的原因。无论如何,我找到了另一种轻松实现智能指针的方法:在 C++ 中实现简单的智能指针。正如您所看到的,它使用特定的类来计算对分配的对象的引用。

(为什么不使用

nullptr
而不是将 0 分配给原始指针?)


0
投票

我看到两个问题::

  1. p
    smartPointer<T>
    类型的对象。它是在堆栈上创建的。请勿删除!!您正在重载函数中删除它以进行分配
  2. 您的 SA 默认构造函数不正确。 用
    p
    初始化
    smartPointer<T>(nullptr)
    。我建议使用构造函数的初始化列表。

除此之外,你的智能指针还不够智能: 请参阅https://www.codeproject.com/Articles/15351/Implementing-a-simple-smart-pointer-in-c

© www.soinside.com 2019 - 2024. All rights reserved.