class AwesomeClass {
public:
AwesomeClass(const AwesomeClass&);
AwesomeClass& operator=(const AwesomeClass&);
// user defined copy operations prevents implicit generation
// of default c-tor and move operations
AwesomeClass() = default;
AwesomeClass(AwesomeClass&&) = default;
AwesomeClass& operator=(AwesomeClass&&) = default;
};-
defaultdeclaration enforces a compiler to generate default implicit implementation for marked functions -
6 special functions can be marked as
default:- default c-tor
- copy c-tor
- copy assignment operator
- move c-tor
- move assignment operator
- destructor
-
Operations declared as
defaultare treated as user-declared (not implicitly-declared) - The default implementation of default c-tor is calling default c-tor for every member
- The default implementation of d-tor is calling d-tor for every member
- The default implementation of copy operations is calling copy operation for every member
- The default implementation of move operations is calling move operation for every member
class NoCopyable { // NoCopyable idiom
public:
NoCopyable() = default;
NoCopyable(const NoCopyable&) = delete;
NoCopyable& operator=(const NoCopyable&) = delete;
};
class NoMoveable { // NoMoveable idiom
NoMoveable(NoMoveable&&) = delete;
NoMoveable& operator=(NoMoveable&&) = delete;
};-
deletedeclaration removes marked function - Calling a deleted function or taking its address causes a compilation error
- No code is generated for deleted function
- Deleted function are treated as user-declared
-
deletedeclaration can be used on any function, not only special class member functions -
deletecan be used to avoid unwanted implicit conversion of function arguments
void integral_only(int a) {
// ...
}
void integral_only(double d) = delete;
integral_only(10); // OK
short s = 3;
integral_only(s); // OK - implicit conversion to int
integral_only(3.0); // error - use of deleted functionMark copy constructors as default.
Delete getY() method in Square and all default (non-parametric) constructors of shapes.
struct A final {};
struct B : A {}; // compilation error
// cannot derive from class marked as finalfinal keyword used after a class/struct declaration blocks inheritance from this class.
struct A {
virtual void foo() const final {}
void bar() const final {} // compilation error, only virtual
// functions can be marked as final
};
struct B : A {
void foo() const {} // compilation error, cannot override
// function marked as final
};final used after a virtual function declaration blocks overriding the implementation in derived classes.
struct Base {
virtual void a();
virtual void b() const;
virtual void c();
void d();
};
struct WithoutOverride : Base {
void a(); // overrides Base::a()
void b(); // doesn't override B::b() const
virtual void c(); // overrides B::c()
void d(); // doesn't override B::d()
};
struct WithOverride : Base {
void a() override; // OK - overrides Base::a()
void b() override; // error - doesn't override B::b() const
virtual void c() override; // OK - overrides B::c(char)
void d() override; // error - B::d() is not virtual
};
override declaration enforces a compiler to check, if given virtual function is declared in the same way in a base class.
Mark Circle class as final.
Mark getX() in Rectangle as final. What is the problem?
Mark all overridden virtual methods. Can you spot the problem?