C++11 默认析构函数C++;11式围棋,头球还是cpp?

C++11 默认析构函数C++;11式围棋,头球还是cpp?,c++11,C++11,在C++11中,构造函数、析构函数和复制/移动操作符的默认实现可以用“=default”指定。在头文件、类定义所在的位置或源文件(cpp)中,将“=default”放在何处 在头文件Test.h中: class Test { public: ~Test() = default; }; 在源文件Test.cpp中: class Test { public: ~Test(); }; #include "Test.h" Test::~Test() = default; 您必须将其

在C++11中,构造函数、析构函数和复制/移动操作符的默认实现可以用“=default”指定。在头文件、类定义所在的位置或源文件(cpp)中,将“=default”放在何处

在头文件Test.h中:

class Test
{
public:
    ~Test() = default;
};
在源文件Test.cpp中:

class Test
{
public:
    ~Test();
};

#include "Test.h"
Test::~Test() = default;

您必须将其放在标题中(无论类定义位于何处,析构函数声明在何处),否则使用您的类的任何人都不会知道这种行为,包括编译器,这会导致其明显的错误行为。

您可以同时执行以下两种操作:

  • 在第一种情况下(标题),析构函数将被视为非用户定义的
  • 在第二种情况(CPP)中,编译器将其视为用户定义的。
用户提供的析构函数是非平凡的,因此类本身必然是非平凡的


除非您有充分的理由支持第二个选项,否则将其放在标题中是通常的做法。

我不同意rubenvb。您不必将显式默认析构函数放在头文件中。 事实上,在一个用例中,将显式默认析构函数放入.cpp文件是完全有效的(并且是必要的)

考虑在头文件中向前声明一个类,并将其与一个智能指针模板一起使用的情况。由于隐式析构函数没有前向声明类的完整声明,因此它无法正确地进行删除。因此,您需要将析构函数定义移到C++文件中,在那里您应该能够访问完整的声明。 在A.hpp中:


请注意,选择第二个选项的一个很好的理由可能是:如果将
Impl
实例包装在
std::unique_ptr
中,则无法在类头文件中实例化默认构造函数,因为
Impl
类此时不完整。什么?您是否暗示在实现文件(.cpp)中定义成员函数会使编译器有明显的错误行为?
#pragma once
#include <memory>
class B;

class A 
{
private:
  std::unique_ptr<B> my_b;
public:
// ~A() = default; 
// defining the default destructor would fail as 
// class B is still a partial class here
  ~A();
};
#include "A.hpp"

// the previously forward declared class B is now included here
#include "B.hpp"

// we can use the default destructor here as B is
// no longer a partial class
A::~A() = default;