关于c++中的析构函数;

about destructors in c++;

本文关键字:析构函数 c++ 关于      更新时间:2023-10-16

我写了一个名为octed_string的类,没有析构函数,它工作得很好,但是它不能返回任何octed_string类型的函数

请看看下面的代码,告诉我哪里出错了。

当我删除析构函数时,它工作了!(cout print 12)

有谁能帮忙吗?
class octed_string
{
private:
    uint8_t *value;
    size_t length;
    size_t allocated;
public:
    octed_string()//constructor
        :value(0),length(0),allocated(0)
    {
    }
    void copy(uint8_t *from, uint8_t *to)
    {
        for (size_t i = 0; i < length; i++)
            *to++ = *from++;
    }
    void allocate()
        {
            if (value == 0)
            {
                allocated = STACK_INITIAL_ALLOC;
                value = new uint8_t[allocated];
            }
            else
            {
                // We need to allocate more memory
                size_t new_allocated = allocated + STACK_CHUNK_ALLOC;
                uint8_t *new_value = new uint8_t[new_allocated];
                // Copy from old stack to new stack
                copy(value, new_value);
                // Delete the old value
                delete [] value;
                allocated = new_allocated;
                value = new_value;
            }
        }
    ~octed_string()//destructor
    {
        if(value)
            delete [] value;
    }
    friend ostream &operator<<(ostream &_output,const octed_string &_str)//opration overloading for cout
    {
        for(int i=0;i<_str.length;i++)
            _output<<(uchar_t)_str.value[i];
        return _output;
    }
    void add(uint8_t input)//this function automatically add space to value (new)
    {
        if (length == allocated)
            allocate();  // Allocate more memory
        value[length++] = _value;
    }
    octed_string sub_string(int start,int end)//( this function has a problem with destructor i think because it return octed_string)
    {
        octed_string a;
        for(int i=start;i<end;i++)
            a.add(a);
        return a;
    }
};
void main()
{
    octed_string o; //object
    o.add(1);
    o.add(2);
    o.add(3);
    cout<<o.sub_string(0,2); //i expect printing 12 but i does not!
}

-----------------------//回答多亏了phresnel,它通过添加以下代码来修复:

octed_string(const octed_string &_input)
    :value(0),length(0),allocated(0)
{
    while(length<_input.length)
    {
        this->add((uchar_t)_input[length]);
    }
}
octed_string& octed_string::operator= (octed_string const& _in)
{
    octed_string tmp(_in);
    return *this;
}

但我仍然不明白原因。有没有人可以提供一些参考资料来了解这个问题?

您需要为octed_string定义复制构造函数和赋值操作符。

当没有析构函数时,它可以工作,因为分配给成员变量value的内存不会被销毁,并且由默认复制构造函数构造的副本指向原始对象(现在已被销毁)所指向的相同的未删除内存。

当你有析构函数时,内存将被删除。

sub_string()返回时创建副本

可能原因

  • 打印错误:您申报的是sub_string,而不是sub_stirng
  • 缺少实现:您的add()函数为空
    • 应该分配一些东西吗?
  • 你没有设计好的副本构造和副本分配:
    • 当您的字符串对象被复制时,其中一个副本将delete值缓冲区
  • 缺少value缓冲区分配。
    • 您根本没有为value缓冲区分配内存

没有实际的代码是不可能有更好的答案的

你想达到什么目标?是否有任何使用std::string无法实现的东西?

注释:

1你如何在里面添加新值?

2前缀下划线(_output)区域是个坏主意

你需要定义一个复制构造函数,例如:
// Assuming value is an array
octed_string::octed_string( const octed_string& rhs) 
    : value( rhs.value ? new uint8_t[ rhs.length ] : 0 )
    , length( rhs.length )
    , allocated( rhs.allocated )
{
}
你还需要一个赋值操作符
octed_string& octed_string::operator= (octed_string const& f)
{
    octed_string tmp( f );
    std::swap( tmp, *this );
    return *this;
}

任何具有指针类型成员变量的类,都需要复制构造函数、重载操作符=和析构函数。

考虑以下代码:

octed_string str1; // suppose this is initialized as desired
octed_string str2 = str1; 

在第二行,调用编译器生成的复制构造函数,逐个复制成员。这里有一个名为value的char_t*成员。因此,str2的值指向与str1相同的内存位置。这被称为浅拷贝。在这种情况下,str1和str2共享相同的内存位置的值,这将导致悬空指针,如果str1超出作用域。下面的代码显示了这种情况的一种可能情况:

octed_string test() {
    octed_string str;
    // Initialize str...
    return str;
}