Best Practices for Using C++ Libraries
The guidance 'don't reinvent the wheel; use libraries' recommends using pre-existing libraries instead of recreating functionality.
Guessing the First Step
Many programming tasks have already been solved by someone else. Reading a file, sorting a list of numbers, and formatting text are all jobs that many programs need, and a great deal of working code already exists for them. Experienced programmers build a habit around this fact: before writing a piece of functionality from scratch, they check whether it already exists. The guidance behind this habit is short: don't reinvent the wheel; use libraries.
What do you think happens?
You need your program to sort a list of numbers. What should you do first?
Reveal answer
Check whether an existing library already provides sorting
The recommended order begins with identifying the task and then checking whether an existing library provides it. Writing code is the last step, not the first.
What a Library Is
A library is code written by someone else that your program can call. Because the functionality already exists in the library, you avoid writing generic functionality yourself.
The important word in the guidance is leveraging. When you leverage a library, work that has already been done carries part of the load for your project. Your program can then focus on its own purpose instead of on generic functionality that many other programs also need.
Separating Generic Work from Unique Logic
Every program contains two kinds of work. Some code is specific to your application, such as the rules of a game or the layout of a report. Other code is generic, such as sorting, parsing, or basic data handling. Generic code is the kind most likely to already exist in a library.
Recognizing which part of your task is generic is the first step toward reusing existing work. Reuse works best when you keep the generic work separate from the logic that is unique to your project. The generic part can be handed to a library, while your own code concentrates on the rules that only your program has.
Sorting out generic and unique work
A teacher's grading program must sort exam scores from highest to lowest and also apply the school's rule that any score below 50 is marked as failing. Which part is generic, and which part is unique to the project?
- 1Name the task
Sorting a list of numbers is a task many programs need, so it is a generic job.
- 2Check the generic part
Comparing and rearranging values is the same whether the numbers are exam scores, prices, or temperatures. This is the kind of work a library can handle.
- 3Identify the unique part
The rule that a score below 50 is failing belongs to this school's grading. No general library knows this rule, so the program must write it.
Sorting is generic and can be reused from a library. The failing-score rule is unique and belongs in the program's own code.
The Decision Order
When you need a piece of functionality, the decision usually follows a simple order. First, identify exactly what the task requires. Second, check whether an existing library already provides that functionality. If it does, the recommended path is to use it. Only when no suitable library exists does writing custom code become the main option.
Mistakes That Cancel Out the Benefits
Using a library only pays off when you actually take the check seriously. The most important mistake is skipping the check, because the source identifies that skip as the thing that leads to duplicated effort. The diagram below compares the two paths.
Common mistake Skipping the check before writing code
Why it failsThe check is what reveals whether the work has already been done. Without it, the same functionality is built again.
Do this insteadIdentify the task and check for an existing library before you write any generic functionality.
Common mistake Rewriting generic functionality that a library already provides
What it looks likeWriting your own sorting routine when a standard library sorting facility is available for the same job.
Why it failsGeneric jobs such as sorting are the kind most likely to already exist in a library, so custom code repeats work that has been done.
Do this insteadKeep your own code for the rules that are unique to your project, and hand generic jobs to the library.
Common mistake Mixing generic work into the application's own logic
Why it failsWhen generic steps are tangled with project-specific rules, it becomes harder to see which part a library could replace.
Do this insteadSeparate generic work from unique logic before you decide what to reuse.
Tracing a Sort in the Standard Library
The source uses an exam-score example to illustrate the principle. The programmer did not have to decide how to compare and move values, because the standard library already handled that generic work. That left the program's own logic free to deal with the exam scores. The code below is an illustrative sketch of the same idea, using the C++ standard library to sort scores.
58 64 72 88 95 - The vector stores the exam scores.
- std::sort from the standard library performs the comparing and rearranging, so the program does not write that logic itself.
- The loop only prints the sorted result; any grading rule for failing scores would be written here in the program's own code.
Applying the Decision to New Tasks
A program must (a) read a list of student names from a text file, (b) sort the names alphabetically, and (c) reject any name that contains a digit because the school's registration rule forbids digits. For each part, decide whether to check for an existing library first or write custom code, and explain why.
Hints
- Ask first whether the job is generic or specific to this school's rules.
- Reading a file and sorting are generic jobs many programs need.
- A registration rule about digits is specific to the project, so it is the kind of logic the program itself must express.
Key Takeaways
- The guidance 'don't reinvent the wheel; use libraries' asks you to check whether existing code already provides a needed piece of functionality before writing it yourself.
- A library is code written by someone else that your program can call, and leveraging it lets your program focus on its own purpose.
- The decision order is to identify the task, check whether a library provides it, use the library if it does, and write custom code only when no suitable library exists.
- Separate generic work, such as sorting or parsing, from the logic unique to your project, because generic work is the most likely to be found in a library.
- Skipping the check leads to duplicated effort, which cancels out the benefit of using libraries.