mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
some minor fixes in the class hierarchy section
closing issue 524
This commit is contained in:
parent
e7f6ecc470
commit
af86ae575e
|
@ -5661,16 +5661,40 @@ not using this (over)general interface in favor of a particular interface found
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
|
||||||
A class is more stable (less brittle) if it does not contain data. Interfaces should normally be composed entirely of public pure virtual functions and a default/empty virtual destructor.
|
A class is more stable (less brittle) if it does not contain data.
|
||||||
|
Interfaces should normally be composed entirely of public pure virtual functions and a default/empty virtual destructor.
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
class my_interface {
|
class my_interface {
|
||||||
public:
|
public:
|
||||||
// ...only pure virtual functions here ...
|
// ...only pure virtual functions here ...
|
||||||
virtual my_interface() {} // or =default
|
virtual ~my_interface() {} // or =default
|
||||||
};
|
};
|
||||||
|
|
||||||
|
##### Example, bad
|
||||||
|
|
||||||
|
class Goof {
|
||||||
|
public:
|
||||||
|
// ...only pure virtual functions here ...
|
||||||
|
// no virtual destructor
|
||||||
|
};
|
||||||
|
|
||||||
|
class Derived : public Goof {
|
||||||
|
string s;
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
|
||||||
|
void use()
|
||||||
|
{
|
||||||
|
unique_ptr<Goof> p {new Derived{"here we go"}};
|
||||||
|
f(p.get()); // use Derived through the Goof interface
|
||||||
|
g(p.get()); // use Derived through the Goof interface
|
||||||
|
} // leak
|
||||||
|
|
||||||
|
The `Derived` is `delete`d through its `Goof` interface, so its `string` is leaked.
|
||||||
|
Give `Goof` a virtual destructor and all is well.
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Warn on any class that contains data members and also has an overridable (non-`final`) virtual function.
|
* Warn on any class that contains data members and also has an overridable (non-`final`) virtual function.
|
||||||
|
@ -5683,7 +5707,27 @@ Such as on an ABI (link) boundary.
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
???
|
struct Device {
|
||||||
|
virtual void write(span<const char> outbuf) = 0;
|
||||||
|
virtual void read(span<char> inbuf) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class D1 : public Device {
|
||||||
|
// ... data ...
|
||||||
|
|
||||||
|
void write(span<const char> outbuf) override;
|
||||||
|
void read(span<char> inbuf) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class D2 : public Device {
|
||||||
|
// ... differnt data ...
|
||||||
|
|
||||||
|
void write(span<const char> outbuf) override;
|
||||||
|
void read(span<char> inbuf) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
A user can now use `D1`s and `D2`s interrchangeably through the interface provided by `Device`.
|
||||||
|
Furthermore, we can update `D1` and `D2` in a ways that are not binarily compatible with older versions as long as all access goes through `Device`.
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user