Item 18:make interfaces Easy-correctly and hard-to-use incorrectly.
"Make the interface easy to use, not easy to misuse", which is an important concept in object-oriented design, good interface in engineering practice is particularly important. When using excellent third-party components, it is often possible to feel the good interface can be so convenient, and even do not need to remember its name and parameters can be called correctly. Anti-self-written API, often someone repeatedly ask how to set this parameter, really failed. Err who can have no, can only in this painful drive hard to reconstruct and learn!
Although I have been out of the Windows development for a long time, but think of the. NET API good design, still will pleasantly surprised.
Anyway
In C + +, it can be said that interfaces are everywhere, and interfaces define how customers interact with your code. If the user misused your interface, you would at least take part of the responsibility. The ideal interface is this:
If the user misused the interface, the code would not compile properly, and if the code was compiled, then your interface would be doing what the customer wanted.
To construct a date correctly
A popular example: Date
the constructor of an object needs to pass in the month, day, and year. However, the client often passes the wrong order when called, and the parameter can be encapsulated as an object to provide type checking:
class Date{ Public: Date(Const Month& m, Const Day& D, Const Year& y);};Date D( Day( -), Month(3), Year(1995)); //Compile Error: type incompatible! Date D(Month(3), Day( -), Year(1995)); //OK
Even so, the user'sMonth
The constructor will still pass in an unreasonable argument (for example,32
), or it is unclear whether the subscript starts at 0 or 1. The solution is predefined for all availableMonth
:
class Month{ Public: Static Month Jan(){ return Month(1); } Static Month Feb(){ return Month(2); }};Date D(Month::Jan(), Day( -), Year(1995));
As Date
you can see from the example above, you can convert the runtime data to the name of the compile period, and you can advance the error check to the compile time. This solves the misuse of the order and scope of the parameters.
Restrictions on the type of operation
Another example from Item 3: Try to use constants, the multiplication operator return value is set to const
to prevent misuse of the assignment:
if(a*b=c)...// 用户的意图本来是判等
Provide a consistent interface
In addition, it is important to provide a consistent interface. For example, STL containers encapsulate incompatible basic data types and provide a very consistent interface for STL algorithms.
For example, STL provides size
attributes to identify the size of a container, which can be arrays, linked lists, strings, dictionaries, and collections. NET all of these sizes are called the Count property. It is not important to use which naming, it is important to provide a consistent interface. It is not only easy to use in applications, but also facilitates the expansion of libraries.
a good interface does not require the user to remember something. Like whatInvestment* createInvestment()
Ask the customer to remember to destroy in time, then the customer probably forgot todelete
Ordelete
A number of times. The solution is to return a smart pointer instead of the original resource, see: Item 13: Using objects to manage resources especially when destroying operations is not simpledelete
, customers also need to remember how to destroy it. And when we return to the smart pointer, we can specifydeleter
To customize the Destroy action:
shared_ptr<Investment> createinvestment(){ //Destroy an investment, you need to do some business to cancel the investment, rather than simply ' delete ' return shared_ptr<Investment>(New Stock, getridofinvestment);}
shared_ptr
The benefits are not just removing the customer's responsibility, but also solving the problem of dynamic memory management across DLLs. In the DLLnew
Object, if in another DLLdelete
Run-time errors tend to occur, butshared_ptr
When a resource is destroyed, it is always called in the DLL that created the smart pointer.delete
, which meansshared_ptr
You can freely pass between DLLs without worrying about cross-DLL issues.
In short, good interfaces are easy to use and are not easily misused. You can provide a consistent interface for built-in types to facilitate proper use. The means of identifying misuse include creating a new type, restricting the operation of the type, restricting the value of the object, and removing the customer's resource management responsibilities.
Unless noted, this blog article is original, reproduced please link to the form of this article address: http://harttle.com/2015/08/09/effective-cpp-18.html
Copyright NOTICE: This article is for bloggers original articles, reproduced please attach the original link.
Item 18: Make the interface easy to use correctly, not easy to misuse effective C + + notes