Catto / Topic Map · Computer Science II Level 2
Computer Science II · 120 h · Topic 7 of 8

Introduction to an advanced language

After C, a language with objects lets you think in pieces that fit together. It is not a fad: it is how a ten-thousand-line project stays understandable.

Objects Classes Encapsulation Exceptions Libraries

01Why functions are not enough

In C a program grows as a list of functions that pass structures to each other. It works until the project reaches a few thousand lines and three problems appear: anyone can touch any field, the same piece of data is validated in twenty places, and adding a case forces you to hunt down all the scattered ifs.

The three ideas that solve this
  • Encapsulation. The data and the operations that touch it live together, and from outside you only see what was chosen to be shown. If the state can only be changed through methods, it is always valid.
  • Inheritance. A class starts from another and adds or changes what it needs, without repeating what is common.
  • Polymorphism. The same method is called on different objects and each one does its own thing. It is what lets you add a new instrument without touching the code that uses them.

It is neither a fad nor an obligation: it is a way to keep a ten-thousand-line project understandable. For a two-hundred-line firmware, C and a structure remain the right answer.

02From structure to class

In CIn C++ or Python
struct Channel with its fieldsThe class, with the same private fields
channel_init(&c, ...)The constructor
channel_read(&c)A method: the object is the implicit first parameter
channel_free(&c)The destructor, or the with block
A function pointer in the structureA virtual method
class Channel:
    def __init__(self, name, scale):
        self.name = name
        self._scale = scale # the underscore says “do not touch me”

    def read(self):
        return self._raw() * self._scale

That explicit self in Python is the same as the implicit this in C++ and the same pointer to the structure that was passed by hand in C. The syntax changes, not the mechanism.

Lab · inheritance and polymorphism

The same code calls measure() on different objects. Choose which one it is and see which implementation runs.

03Dynamic dispatch

When a method is called on an object, the language has to decide which of the implementations to run. If that decision is made at compile time, it is static dispatch; if it is made at run time, by looking at the object’s real type, it is dynamic, and that is what makes polymorphism possible.

for device in bench: # multimeter, oscilloscope, power supply…
    print(device.describe())  # each one answers in its own way

The loop does not know and does not care what is inside the list. Adding a new instrument does not force you to touch it: it is enough for the new class to implement the same methods. That is what you gain.

How it works inside

In C++, each class with virtual methods has a virtual function table, and each object stores a pointer to its class’s table. Calling a virtual method means reading that pointer, looking up the entry and jumping: two more indirections than an ordinary call. In Python it is even more dynamic —the name is looked up in a dictionary— and that is why it is more flexible and slower.

04Abstract types and exceptions

An abstract data type is defined by what can be done with it, not by how it is built. A stack is “push, pop and look at the top”, regardless of whether inside there is an array or a linked list. The standard library is exactly that: tested containers that no longer have to be written.

NeedC++Python
A sequence that growsstd::vectorlist
Look up by keystd::map, unordered_mapdict
No duplicatesstd::setset
Double-ended queuestd::dequecollections.deque
Memory that frees itselfunique_ptr, shared_ptrGarbage collector

Exceptions

In C, a function reports an error by returning a code that almost nobody checks. Exceptions separate the normal path from the error path:

try:
    v = instrument.measure()
except TimeoutError:
    log("the device did not respond")
finally:
    instrument.close() # this runs no matter what

Three rules: catch only what you know how to handle —an empty except hides programming errors—, always release with finally or with with, and do not use exceptions for normal flow, because they are expensive and confusing.

05Which one to use in electronics

JobReasonable tool
Firmware for a small microcontrollerC, and C++ without exceptions or dynamic allocation
Large firmware, with layersModern C++: classes, templates, constexpr
Lab tool, interface, analysisPython, for how quickly it can be written
Processing measurements and plottingPython with NumPy and Matplotlib
Whatever has to flyC or C++, or the critical part in C called from Python

The most useful combination for an electronics engineer is to know both: C or C++ for the device and Python for everything around it —automating the bench, processing the measurements, putting together the report—. They do not compete: they are used in different layers of the same project.

06In the lab

Exercise 1 · The same thing, twice

Implement a stack in C with a structure and functions, and in C++ or Python as a class. Compare how many ways there are to misuse it in each case.

Exercise 2 · An instrument bench

Define a base class Instrument with connect, measure and describe, and three derived classes. Traverse a mixed list calling the same methods, and then add a fourth class without touching the loop.

Exercise 3 · Errors that cannot be ignored

Write a function that reads the serial port and raises an exception if the device does not respond. Check with finally that the port ends up closed even when it fails.

07Common mistakes

  • Making classes for everything. If there is no state to protect, a function is enough.
  • Deep inheritance. Four levels are harder to follow than a little repetition.
  • Exposing every attribute and losing the one guarantee that encapsulation gave.
  • Catching Exception and carrying on as if nothing had happened, hiding real errors.
  • Using exceptions for normal flow, such as exiting a loop.
  • Assuming that Python is slow at everything: what is slow is the hand-written loop; with NumPy the calculation runs in C.

08Self-assessment

What is encapsulation and what does it guarantee?

Keeping the data and the operations together, and exposing only what is necessary. It guarantees that the state changes only through validated paths.

What does polymorphism allow that would otherwise be costly?

Adding a new type without touching the code that uses it: the loop that traverses the list of instruments stays the same.

How does C++ resolve a call to a virtual method?

Through the virtual function table: the object stores a pointer to its class’s table and the call jumps to the corresponding entry, at run time.

Why is except: pass wrong?

Because it catches everything, including programming errors, and hides them. You should catch only the exceptions you know how to handle.

What does finally do?

It runs that block whether or not there is an exception: it is where the port, the file or the connection is closed.

Is it a good idea to use objects on a microcontroller with 2 kB of RAM?

Simple classes, yes; exceptions and dynamic allocation, no. The tool is chosen for the problem, not out of habit.

09Further reading

  • Bjarne Stroustrup. A Tour of C++. 3rd ed., Addison-Wesley, 2022. Modern C++ in two hundred pages, written by its creator.
  • Mark Lutz. Learning Python. 5th ed., O'Reilly, 2013. Thorough and careful about the language’s object model.
  • Erich Gamma et al. Design Patterns. Addison-Wesley, 1994. The classic patterns. It is best read after having suffered the problems they solve.
  • Robert C. Martin. Clean Code. Prentice Hall, 2008. Debatable on several points, but it installs the right question: will this still be understood a year from now.
Development of the topic “Introduction to an advanced language” of Computer Science II (Level 2), based on the curriculum of the UTN Electronic Engineering program, 2023 curriculum — Ordinance No. 1849 of the UTN Higher Council. Back to the Topic Map · catto.ar