你看到这个C ++代码有什么问题吗?

时间:2011-04-26 09:19:35

标签: c++ destructor

#include<iostream>
#include<conio.h>
using namespace std;
class A
{
public:
       int *p;      
A()
{
   p =new int;
}

~A()
{
delete p;   //Is this what i am doing is correct?
cout << "in A's destructor"<<endl;
}

};

int main()
{
A *obj=new A;
delete obj;    
getch();
}

这个程序,我已经在Dev c ++中执行并编译并执行正常。 但我怀疑这不是很好。特别是在我说delete P

的析构函数中 我错了吗?

4 个答案:

答案 0 :(得分:11)

该代码在逻辑上很合适(您询问的new / delete部分),但在其他方面设计得很糟糕。

首先,如果class A拥有堆分配的intint只有class A个对象存在的生命),那么使用{{1}创建它是没有意义的,使它成为new的成员变量会更有效率。其次,你不应该让它class A - 打破封装并允许大量滥用。

最后,您仍然允许复制构造函数和赋值运算符,并且未实现,因此每次复制类对象时都会得到浅复制。您应该适当地实施它们,或prohibit them

public分配了delete的变量的部分完全正常。

答案 1 :(得分:2)

我看到此代码有4个问题:

  • new
  • 的两种用法
  • delete
  • 的两种用法

可能是你缩减的代码在原始实现方面有点缺乏,或者你来自一种语言,其中所有内容都是new,但代码原来远不是惯用的C ++。 / p>

惯用的重写:

#include<iostream>

class A
{
public:
  int p;

  ~A() { std::cout << "~A" << std::endl; } // force a flush with endl
};

int main(int argc, char* argv[])
{
  {
    A obj;
  } // for destruction to occur before getch

  // use streams instead of getch
  char a;
  std::cin >> a;

  // the signature says it returns an int...
  return 0;
}

答案 2 :(得分:1)

正如尖锐的指出,在dtor中使用delete是完全有效的。 delete null在std中定义为noop。

但是,对于这样的事情,请考虑使用shared_ptr或类似的东西......

HTH

马里奥

答案 3 :(得分:1)

在这种情况下,您还需要定义自己的复制构造函数和赋值运算符(或将它们声明为私有以使类成为不可复制的);默认的复制构造函数和赋值运算符执行浅复制。也就是说,它们复制指针,而不是指针的内容。所以,如果你这样做:

A x;
A y = x;

x.py.p都指向相同的位置,因此当它们被破坏时,它们会尝试释放相同的内存,从而产生未定义的行为。

要解决此问题,请定义您自己的复制构造函数和赋值运算符,以复制int:

class A
{
public:
        A() : p(new int) {}
        A(const A& obj) : p(new int(*obj.p)) {}
        ~A() { delete p; }
        A& operator=(const A& obj) { *p = *obj.p; }
private:
        int *p;
};
相关问题