我写了一个名为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;
}
但我仍然无法理解原因。任何机构都可以参考这个问题吗?
答案 0 :(得分:11)
您需要为octed_string
定义复制构造函数和赋值运算符。
当你没有析构函数时,它可以正常工作,因为为成员变量value
分配的内存不会被破坏,并且由默认复制构造函数构造的副本引用与原始(现在已销毁)对象相同的未删除内存
当你有一个析构函数时,内存将被删除。
当sub_string()
返回时创建副本。
答案 1 :(得分:1)
可能的原因:
sub_string
,但未宣布sub_stirng
。add()
功能为空
delete
值缓冲区 value
缓冲区的分配。
value
- 缓冲区分配内存 如果没有实际的代码,那么更好的答案是不可能的。
答案 2 :(得分:1)
你想要达到什么目的?是使用std :: string无法实现的吗?
几点意见:
1你如何在add中创造价值?
2前缀下划线(_output)区域是个坏主意
3您需要定义一个复制构造函数,例如:
// 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 )
{
}
4您还需要一个赋值运算符
octed_string& octed_string::operator= (octed_string const& f)
{
octed_string tmp( f );
std::swap( tmp, *this );
return *this;
}
答案 3 :(得分:0)
任何具有类型指针的成员变量的类,需要复制构造函数,重载operator =和析构函数。
请考虑以下代码:
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;
}
同样的故事适用于对象的分配。