Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 一个变量或对象的内存在程序结束时自动终止,为什么我们使用析构函数呢?_C++_Oop_Constructor_Destructor - Fatal编程技术网

C++ 一个变量或对象的内存在程序结束时自动终止,为什么我们使用析构函数呢?

C++ 一个变量或对象的内存在程序结束时自动终止,为什么我们使用析构函数呢?,c++,oop,constructor,destructor,C++,Oop,Constructor,Destructor,在下面的程序中,我们在局部范围内创建圆形对象,因为我们没有使用新关键字。我们知道,一个变量或对象的内存在程序结束时自动终止,而不是为什么我们使用析构函数 #include<iostream> using namespace std; class Circle //specify a class { private : double radius; //class data members public: Circle() //

在下面的程序中,我们在局部范围内创建圆形对象,因为我们没有使用新关键字。我们知道,一个变量或对象的内存在程序结束时自动终止,而不是为什么我们使用析构函数

#include<iostream>
using namespace std;     
class Circle //specify a class
{
    private :
        double radius; //class data members
    public:
        Circle() //default constructor
        {
            radius = 0;
        }           
        void setRadius(double r) //function to set data
        {
            radius = r;
        }
        double getArea()
        {
            return 3.14 * radius * radius;
        }
        ~Circle() //destructor
        {} 
};

int main()
{
    Circle c; //defalut constructor invoked   
    cout << c.getArea()<<endl;     
    return 0;
}
#包括
使用名称空间std;
类循环//指定一个类
{
私人:
双半径;//类数据成员
公众:
Circle()//默认构造函数
{
半径=0;
}           
void setRadius(双r)//用于设置数据的函数
{
半径=r;
}
双getArea()
{
返回3.14*半径*半径;
}
~Circle()//析构函数
{} 
};
int main()
{
圈c;//调用了defalut构造函数

cout嗯,有时候你的对象可能有指针或者需要释放的东西之类的东西

例如,如果您的Circle类中有一个poiner,则需要取消分配该poiner以避免内存泄漏


至少我是这样知道的。

嗯,有时候你的对象可能有指针或需要释放的东西之类的东西

例如,如果您的Circle类中有一个poiner,则需要取消分配该poiner以避免内存泄漏


至少我是这样知道的。

假设内存是无限资源是非常危险的。想想一个实时应用程序,它需要全天候运行,并以高速率(比如说每秒1000条消息)侦听数据馈送。每条消息大约1KB,每次它分配一个新内存块(显然是在堆中)对于每条消息。总共,我们每天需要大约82 GB。如果您不管理内存,现在您可以看到将发生什么。我不是说复杂的内存池技术或类似技术。通过简单的算术计算,我们可以看到我们无法将所有消息存储在内存中。这是您考虑内存管理的另一个示例ent(从分配和释放的角度来看)。

假设内存是无限资源是非常危险的。考虑一个实时应用程序,它需要全天候运行,并以高速率(比如每秒1000条消息)侦听数据馈送。每条消息大约1KB,每次分配一个新的内存块(显然在堆中)对于每条消息。总共,我们每天需要大约82 GB。如果您不管理内存,现在您可以看到将发生什么。我不是说复杂的内存池技术或类似技术。通过简单的算术计算,我们可以看到我们无法将所有消息存储在内存中。这是您考虑内存管理的另一个示例ent(从分配和解除分配的角度)。

首先,您不需要显式定义析构函数。一个析构函数将由编译器自动定义。如果您这样做,请根据c++11中的规则3或规则5(如果您声明以下任何一项):复制构造函数、复制赋值、移动构造函数(c++11)、移动赋值(c++11)或析构函数,您应该显式定义它们

继续。过于简单化了,RAII原则规定分配的每个资源都必须被释放。此外,在分配的每个资源上必须存在一个且只有一个所有者,一个负责释放资源的对象。这就是资源管理。这里的资源可能意味着必须在我们面前初始化的任何东西使用后释放,例如动态分配内存、系统处理程序(文件处理程序、线程处理程序)、套接字等。实现的方式是通过构造函数和析构函数。如果您的对象负责销毁资源,则当您的对象死亡时,应销毁该资源。析构函数将发挥作用

您的示例不是很好,因为您的变量存在于main中,所以它将在整个程序中存在

考虑函数中的局部变量:

int f()
{
    Circle c; 
    // whatever    
    return 0;
}
每次调用函数
f
,都会创建一个新的
Circle
对象,并在函数返回时将其销毁

现在作为一个练习,考虑下列程序有什么不对:

std::vector foo() {
  int *v = new int[100];

  std::vector<int> result(100);

  for (int i = 0; i < 100; ++i) {
    v[i] = i * 100 + 5;
  }


  //
  //  .. some code
  //

  for (int i = 0; i < 100; ++i) {
    result.at(i) = v[i];
  }

  bar(result);

  delete v;

  return result;
}
如果函数在任何点抛出,将无法到达
delete v
,资源将永远不会被删除。因此,您必须有一个明确的资源所有者负责该资源的销毁。您知道构造函数和析构函数将帮助我们:

class Responsible() { // looks familiar? take a look at unique_ptr
  private:
    int * p_ = nullptr;
  public:
    Responsible(std::size_t size) {
      p_ = new int[size];
    }
    ~Responsible() {
      delete p_;
    }
    // access methods (getters and setter)
};
因此,该计划变成:

std::vector foo() {
  Responsible v(100);      

  //
  //  .. some code
  //

  return result;
}

现在,即使函数将抛出,资源也将得到适当的管理,因为当出现异常时,堆栈是非故意的,也就是说,所有的局部变量都被销毁了……幸运的是,
Responsible
的析构函数将被调用。

首先,您不需要显式定义析构函数。一个析构函数将自动执行由编译器定义。如果您这样做,根据c++11中的3或5规则,如果您声明以下任何一项:复制构造函数、复制赋值、移动构造函数(c++11)、移动赋值(c++11)或析构函数,则应显式定义所有这些项

继续。过于简单化了,RAII原则规定分配的每个资源都必须被释放。此外,在分配的每个资源上必须存在一个且只有一个所有者,一个负责释放资源的对象。这就是资源管理。这里的资源可能意味着必须在我们面前初始化的任何东西使用后释放,例如动态分配内存、系统处理程序(文件处理程序、线程处理程序)、套接字等。实现的方式是通过构造函数和析构函数。如果您的对象负责销毁资源,则当您的对象死亡时,应销毁该资源。析构函数将发挥作用

您的示例并不太好,因为您的变量位于ma中
std::vector foo() {
  Responsible v(100);      

  //
  //  .. some code
  //

  return result;
}