【问题标题】:Initializing parent class' pointer using initializer list使用初始化列表初始化父类的指针
【发布时间】:2021-08-08 00:21:08
【问题描述】:

我有一个类字符串:

    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;
    }
};

另一个类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;
}

【问题讨论】:

  • 两个类的复制构造函数和赋值运算符都损坏了。这可能是造成问题的原因。
  • 我该如何解决?你说它坏了是什么意思?
  • 无关:istream&amp; operator&gt;&gt;(istream&amp; input, stringsFromNumbers&amp; obj) 中的 cin.ignore(); 会让您后悔的。迟早你会发现自己在使用&gt;&gt; 而不会在需要ignoreing 的流中产生垃圾,并且你会丢弃你不想丢弃的数据。永远不要在 IO 事务之前丢弃数据。而是在流中留下垃圾的 IO 操作之后丢弃。
  • 感谢您的指导,但这并不能解决我面临的问题?你能帮忙吗?
  • 建议:备份您的代码并将其破解为minimal reproducible example。通常,您不必完成 MRE 的制作,因为在制作过程中进行了一些分而治之的过程,您将减少 bug 周围的噪音,足以发现并修复 bug。如果您在 MRE 流程结束时仍未找到答案,请编辑问题并添加 MRE。

标签: c++ string pointers inheritance dynamic-memory-allocation


【解决方案1】:

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

这些类中只有一个应该负责管理ptr 的生命周期。从stringsFromNumbers::~stringsFromNumbers 中删除delete[]。

如果在其他情况下您有正当理由在子类的析构函数中释放数组,请确保父类析构函数能够处理新状态(例如,通过将 ptr 设置为 @987654329 @ 删除后),但一般情况下,您应该避免让两个类共同负责释放内存的复杂性。

【讨论】:

  • 非常感谢您帮助我解决这个问题,我没有注意到这可能是个问题。解决了我的问题,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
相关资源
最近更新 更多