关于c++中的析构函数;
about destructors in c++;
我写了一个名为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
。 缺少实现:您的 - 应该分配一些东西吗?
- 你没有设计好的副本构造和副本分配:
- 当您的字符串对象被复制时,其中一个副本将
delete
值缓冲区
缺少 - 当您的字符串对象被复制时,其中一个副本将
- 您根本没有为
value
缓冲区分配内存 - 。
add()
函数为空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;
}
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误