使用初始化列表初始化父 class' 指针

Initializing parent class' pointer using initializer list

我有一个 class 个字符串:

    class strings
    {
    protected:
    string *ptr;
    int size;
public:
    strings() {
        ptr = NULL;
        size = -1;
    }
    strings(int size) {
        this->size = size;
        ptr = new string[size];
    }
    string* retPtr() {
        return ptr;
    }
    void setPtr(int size)
    {
        ptr = new string[size];
        this->size = size;
    }
    strings(const strings& obj) {
        this->size = obj.size;
        for (int i = 0;i < size;++i)
            this->ptr[i] = obj.ptr[i];
    }
    friend istream& operator>>(istream& input, strings& obj) {
        cin.ignore();
        cout << "Enter " << obj.size << " string one by one:\n";
        for (int i = 0;i < obj.size;++i)
        {
            getline(input, obj.ptr[i]);
        }
        return input;
    }
    friend ostream& operator<<(ostream& output, const strings& obj) {
        cout << "Strings are:\n";
        for (int i = 0;i < obj.size;++i)
            output << obj.ptr[i] << "\n";
        return output;
    }
    void operator =(const strings& obj)
    {
        this->size = obj.size;
        for (int i = 0;i < size;++i)
            ptr[i] = obj.ptr[i];
    }
    ~strings()
    {
        delete[]ptr;
    }
};

另一个class stringsFromNumbers:

class stringsFromNumbers:public strings
{
    int numbers;
public:
    stringsFromNumbers(){
        numbers = -1;
    }
    stringsFromNumbers(int size, int numbers):strings(size){
        this->numbers = numbers;
    }
    stringsFromNumbers(const stringsFromNumbers& obj)
    {
        this->numbers = obj.numbers;
        this->size = obj.size;
        for (int i = 0;i < size;++i)
            this->ptr[i] = obj.ptr[i];
    }
    friend istream& operator>>(istream& input, stringsFromNumbers& obj) {
        cin.ignore();
        cout << "Enter " << obj.size << " string one by one:\n";
        for (int i = 0;i < obj.size;++i)
        {
            getline(cin, obj.ptr[i]);
        }
        return input;
    }
    friend ostream& operator<<(ostream& output, const stringsFromNumbers& obj) {
        cout << "Numbers are: " << obj.numbers;
        cout << "\nStrings are:\n";
        for (int i = 0;i < obj.size;++i)
            output << obj.ptr[i] << "\n";
        return output;
    }
    void operator =(const stringsFromNumbers& obj)
    {
        this->numbers = obj.numbers;
        this->size = obj.size;
        for (int i = 0;i < size;++i)
            this->ptr[i] = obj.ptr[i];
    }
    ~stringsFromNumbers()
    {
        delete[] ptr;
    }
};

每当我尝试执行这行代码时:

stringsFromNumbers obj2(N, P);

其中 N 和 P 是有效整数,我收到“访问读取冲突”,您是否发现代码有问题? 我已经坚持了将近2个小时。我试过调试和修复它,我也尝试过多种其他方法。异常将我带到这个函数:

inline void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
    if (_Myproxy) { // proxy allocated, drain it
        _Lockit _Lock(_LOCK_DEBUG);

        for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
            (*_Pnext)->_Myproxy = nullptr;
        }

        _Myproxy->_Myfirstiter = nullptr;
    }
#endif // _ITERATOR_DEBUG_LEVEL == 2
}

问题很可能出在这个函数上,但如何解决?

stringsFromNumbers(int size, int numbers):strings(size){
    this->numbers = numbers;
}

stringsFromNumbers::~stringsFromNumbersstrings::strings都在ptr上调用了delete[],因此尝试释放数组两次;第二次出现问题。

这些 class 中只有一个应该负责管理 ptr 的生命周期。从 stringsFromNumbers::~stringsFromNumbers.

中删除 delete[]

如果在某些其他情况下您有正当理由在子class的析构函数中释放数组,请确保父class析构函数能够处理新的状态(例如,在删除它后将 ptr 设置为 nullptr),但通常您应该避免让两个 class 共享释放内存的责任的复杂性。