diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 39fcf71..a3faf9c 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -1,6 +1,6 @@ # C++ Core Guidelines -May 2, 2019 +June 16, 2019 Editors: @@ -6303,6 +6303,7 @@ Worse, a direct or indirect call to an unimplemented pure virtual function from virtual void f() = 0; // not implemented virtual void g(); // implemented with Base version virtual void h(); // implemented with Base version + virtual ~Base(); // implemented with Base version }; class Derived : public Base { @@ -6975,8 +6976,6 @@ It's simple and clear: * `override` means exactly and only "this is a non-final overrider." * `final` means exactly and only "this is a final overrider." -If a base class destructor is declared `virtual`, one should avoid declaring derived class destructors `virtual` or `override`. Some code base and tools might insist on `override` for destructors, but that is not the recommendation of these guidelines. - ##### Example, bad struct B { @@ -7258,7 +7257,7 @@ Copying a polymorphic class is discouraged due to the slicing problem, see [C.67 class B { public: virtual owner clone() = 0; - virtual ~B() = 0; + virtual ~B() = default; B(const B&) = delete; B& operator=(const B&) = delete; @@ -7267,7 +7266,7 @@ Copying a polymorphic class is discouraged due to the slicing problem, see [C.67 class D : public B { public: owner clone() override; - virtual ~D() override; + ~D() override; }; Generally, it is recommended to use smart pointers to represent ownership (see [R.20](#Rr-owner)). However, because of language rules, the covariant return type cannot be a smart pointer: `D::clone` can't return a `unique_ptr` while `B::clone` returns `unique_ptr`. Therefore, you either need to consistently return `unique_ptr` in all overrides, or use `owner<>` utility from the [Guidelines Support Library](#SS-views). @@ -7543,6 +7542,7 @@ Without a using declaration, member functions in the derived class hide the enti public: virtual int f(int i) { std::cout << "f(int): "; return i; } virtual double f(double d) { std::cout << "f(double): "; return d; } + virtual ~B() = default; }; class D: public B { public: @@ -7630,6 +7630,7 @@ That can cause confusion: An overrider does not inherit default arguments. class Base { public: virtual int multiply(int value, int factor = 2) = 0; + virtual ~Base() = default; }; class Derived : public Base { @@ -7657,7 +7658,7 @@ If you have a class with a virtual function, you don't (in general) know which c ##### Example - struct B { int a; virtual int f(); }; + struct B { int a; virtual int f(); virtual ~B() = default }; struct D : B { int b; int f() override; }; void use(B b) @@ -7704,6 +7705,7 @@ Flag all slicing. struct B { // an interface virtual void f(); virtual void g(); + virtual ~B(); }; struct D : B { // a wider interface @@ -21514,6 +21516,8 @@ Here is an example of the last option: p->post_initialize(); return p; } + + // ... };