【问题标题】:Strange copy constructor and destructor error奇怪的复制构造函数和析构函数错误
【发布时间】:2020-07-02 07:05:54
【问题描述】:

我有一个类,但我不断从析构函数中收到一些错误。 这是类:

#pragma once
class Number
{
    int bas;
    char* val;
public:
    Number(const char* value, int base); 
    Number(const Number& x);
    ~Number();
    void SwitchBase(int newBase);
    void Print();
    int  GetDigitsCount();
    int  GetBase(); 
};

这是cpp文件:

#include "Number.h"
#include <iostream>
Number::Number(const char* value, int base)
{
    int a = -1;
    do
    {
        a++;
    } while (value[a] != '\0');
    val = new char[a + 1];
    for (int i = 0; i <= a; i++)
        val[i] = value[i];
    bas = base;
}

Number::Number(const Number& x)
{
    int a = -1;
    bas = x.bas;
    do
    {
        a++;
    } while (x.val[a] != '\0');
    delete[]val;
    val = new char[a + 1];
    int i;
    for (i = 0; i <= a; i++)
        val[i] = x.val[i];
}
Number::~Number()
{
    delete[]val;
}
void Number::Print()
{
    std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
}
int Number:: GetDigitsCount()
{
    int l = 0;
    do
    {
        l++;
    } while (val[l] != '\0');
    return l;
}

这是主要的:

int main()
{
    Number x("123", 10),y("111",10),z("0",10);
    z = y;
    z.Print();
}

我不断收到此错误: 指定给 RtlValidateHeap(010C0000, 010C8DD8) 的地址无效 如果我在 main 中进行此更改,它可以正常工作,但这并不是我真正想要的......

int main()
{
    Number x("123", 10),y("111",10);
    Number z = y;
    z.Print();
}

我该如何解决这个问题?我想不通...

【问题讨论】:

标签: c++ class destructor copy-constructor


【解决方案1】:

您的 Number 类缺少赋值运算符。由于您在 main 中使用了赋值运算符,因此默认赋值运算符将在您退出 main 时导致双重删除,这解释了错误。

它还解释了为什么当您将 main 更改为使用复制构造函数而不是赋值运算符时错误消失了。

您应该查看copy and swap 习语,以了解如何轻松高效地实现复制构造函数和赋值运算符。

或者,您也可以使用std::string,而不是手动分配内存。这将消除编写析构函数、复制构造函数和赋值运算符的需要。这是最好的解决方案。

【讨论】:

    【解决方案2】:

    这是一个使用 std::string 的代码示例:

    #include <iostream>
    #include <string>
    
    class Number
    {
        int bas;
        std::string val;
    public:
        Number(std::string, int base); 
        Number(const Number& number);
        Number& operator= (const Number& number);
        ~Number()=default;
        void Print();
        int  GetDigitsCount();
    };
    
    
    Number::Number(std::string value, int base)
    {
        val=value;
        bas=base;
    }
    
    Number::Number(const Number& number)
    {
        val=number.val;
        bas=number.bas;
    }
    
    Number& Number::operator= (const Number& number)
    {
        val=number.val;
        bas=number.bas;
        return *this;
    }
    
    void Number::Print()
    {
        std::cout << "Numarul este: " << val<< std::endl << "Baza este: " << bas<<std::endl;
    }
    int Number:: GetDigitsCount()
    {
        return val.size();
    }
    
    int main()
    {
        Number x("123", 10),y("111",10),z("0",10);
        Number k(y);
        k.Print();
    }
    

    【讨论】:

    • 如果您使用std::string,则无需编写显式复制构造函数和赋值运算符。这是要点之一。
    • 谢谢,我不得不在没有字符串库的情况下这样做,这就是我没有使用它们的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多