鉴于代码:
#include<iostream>
using namespace std;
class String
{
char *pstr;
unsigned size;
public:
String(){ pstr=0;size=0;}
String(const char *);
void show(){ cout << pstr << endl ; }
~String () { cout << "In Dtor" << endl; delete [] pstr; }
};
String::String(const char * cptr)
{
size = strlen (cptr) + 1;
cout << "String is - " << cptr << " - of size " << size - 1 << endl ;
pstr = new char [ size ] ;
for ( int i = 0 ; i < size ; i++)
pstr[ i ] = cptr [ i ];
}
int main()
{
String s("Hello World");
s.show();
s.~String();
}
输出:
String is - Hello World - of size 11
Hello World
In Dtor
----Debug Assertion Failure----
In Dtor
为什么再次调用析构函数?当我调用析构函数?
什么是断言失败?
这段代码也有效吗?
char * ptr=0;
void fun()
{
const char * p = "Hello World";
int size = strlen(p )+ 1;
cout << size << endl;
ptr = (char *)malloc(size);
for ( int i = 0 ; i < size ; i++)
ptr[ i ] = p [ i ];
cout << p << endl << ptr << endl ;
}
int main()
{
fun();
free (ptr); --> Note
}
指针可以从另一个函数中释放吗?这是我在这里想要了解的主要内容。
答案 0 :(得分:10)
你不应该手动调用析构函数 - 当s
超出最终'}'的范围时会调用析构函数
断言失败意味着称为assert(somecondition)
和某些条件的东西是错误的。这是一种用于验证您的假设的技术 - 如果您的代码依赖于某些特定条件为真,并且该条件确实应该为真,除非您有错误,那么您插入一个断言。
然后您可以选择在启用断言的情况下进行编译 - 这意味着如果您的假设错误,您将会遇到这样的错误。对于发布版本,您经常禁用断言 - 没有为assert语句生成代码,并且没有额外的运行时成本。
有些情况下,手动调用析构函数是正确的 - 在您了解并使用“placement new”之前,您不需要这样做。
答案 1 :(得分:1)
除了Erik已经说过的话:
删除手动析构函数调用后,您的代码仍然容易被双重删除:您必须禁用复制构造函数/赋值运算符,或者正确实现它们(如果您坚持拥有堆分配的内存,则需要引用计数)。