Concepts / Best Practices for Using C++ Libraries

Best Practices for Using C++ Libraries

The guidance 'don't reinvent the wheel; use libraries' recommends using pre-existing libraries instead of recreating functionality.

  • Programming

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?

  • Start writing a sorting routine from scratch

  • Check whether an existing library already provides sorting

  • Ask the user to sort the list themselves

Reveal answer
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

Definition

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.

Worked example

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?

  1. 1
    Name the task

    Sorting a list of numbers is a task many programs need, so it is a generic job.

  2. 2
    Check 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.

  3. 3
    Identify 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.

Result

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.

Identify the taskLibrary provides it?Use the libraryWrite custom codeYesNo suitable library
For a given task, the first question is what the task requires. The next question is whether a suitable library already provides it. Custom code is written only when the answer is no.

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.

Write sorting codeDuplicated effortCheck for a libraryCall existing sortExam grading logic
When the check is skipped, the programmer writes generic sorting code and the effort is duplicated. When the check comes first, the existing library handles sorting and the program's own logic receives the attention.
  • Common mistake

    Skipping the check before writing code

    Why it fails

    The check is what reveals whether the work has already been done. Without it, the same functionality is built again.

    Do this instead

    Identify 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 like

    Writing your own sorting routine when a standard library sorting facility is available for the same job.

    Why it fails

    Generic 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 instead

    Keep 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 fails

    When generic steps are tangled with project-specific rules, it becomes harder to see which part a library could replace.

    Do this instead

    Separate 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.

cpp
Output
58 64 72 88 95 
Notes on the code
  • 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

MEDIUM

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.

Related concepts

More concepts starting with B