Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closes #1446 #1448

Merged
merged 1 commit into from
Aug 1, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions CppCoreGuidelines.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# <a name="main"></a>C++ Core Guidelines

May 2, 2019
June 16, 2019


Editors:
Expand Down Expand Up @@ -6305,6 +6305,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 {
Expand Down Expand Up @@ -6977,8 +6978,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 {
Expand Down Expand Up @@ -7260,7 +7259,7 @@ Copying a polymorphic class is discouraged due to the slicing problem, see [C.67
class B {
public:
virtual owner<B*> clone() = 0;
virtual ~B() = 0;
virtual ~B() = default;

B(const B&) = delete;
B& operator=(const B&) = delete;
Expand All @@ -7269,7 +7268,7 @@ Copying a polymorphic class is discouraged due to the slicing problem, see [C.67
class D : public B {
public:
owner<D*> 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<D>` while `B::clone` returns `unique_ptr<B>`. Therefore, you either need to consistently return `unique_ptr<B>` in all overrides, or use `owner<>` utility from the [Guidelines Support Library](#SS-views).
Expand Down Expand Up @@ -7545,6 +7544,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:
Expand Down Expand Up @@ -7632,6 +7632,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 {
Expand Down Expand Up @@ -7659,7 +7660,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)
Expand Down Expand Up @@ -7702,6 +7703,7 @@ Flag all slicing.
struct B { // an interface
virtual void f();
virtual void g();
virtual ~B();
};

struct D : B { // a wider interface
Expand Down Expand Up @@ -21507,6 +21509,8 @@ Here is an example of the last option:
p->post_initialize();
return p;
}

// ...
};


Expand Down