super() in Python

The primary purpose of super() in Python is to call an overridden base class method in a derived class, as super does in other languages.
This is usually done so that a derived class method can augment a base class one by calling it before or after its own code, rather than completely replacing it.

class Derived(Base):
    def method(self, arg):
        # Maybe do something here
        super(Derived, self).method(arg)
        # Could so something here as well

The super() function actually works by returning an object of a proxy class that delegates calls to the parent.
The advantage of using super() in this case is that you don’t need to explicitly name the base class, which aids maintainability.

The super() function can also be used in more complex multiple inheritance situations, where it can do things like delegate to a sister class.
These uses of super are described in Python’s super() considered super!.

Virtual destructors

You need a virtual destructor whenever you want to delete a derived class object from a base class pointer. This is because if the base class destructor is non-virtual, the derived class destructor will not be called, as the following code demonstrates:

#include <iostream>

class Base 
{
public:
    ~Base() 
    {
        std::cout << "Base destructor called" << "\n";
    }
};

class Derived : public Base
{
    ~Derived()
    {
        std::cout << "Derived destructor called" << "\n";
    }
};

int main()
{
    Base* b = new Derived();
    delete b;
}

This prints:

Base destructor called

You need to add the virtual keyword to the first line of the destructor definitions as follows:

virtual ~Base()
virtual ~Derived()

And then the output becomes:

Derived destructor called
Base destructor called

This applies even if the derived class does not contain any resources that might be leaked if its destructor is not called, since failure to call a derived class destructor is undefined behaviour.

This means that classes designed to be bases should declare a virtual destructor so that derived classes can override it. It also means that classes that do not have a virtual destructor should not be used as bases, as this means that the class derived from them could not safely be used on a derived class pointer.

Enums in Python

Enums have been added to Python 3.4 with PEP 435. They have also been backported to versions 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4 with enum34.

To declare an enum, declare a subclass of enum.Enum:

from enum import Enum

class Colour(Enum):
   red = 1
   yellow = 2
   blue = 3

You can access the enumerated values (and names) in the following ways:

>>> Colour.red
<Colour.red: 1>
>>> Colour['red']
<Colour.red: 1>
>>> Colour(1)
<Colour.red: 1>
>>> Colour.red.name
'red'
>>> Colour.red.value
1

You can also treat the enumeration as an iterable:

>>> for colour in Colour:
...     print colour
...
Colour.red
Colour.yellow
Colour.blue
>>> len(Colour)
3

Extern “C”

The C++ compiler needs to “mangle” the names of functions when it compiles them because there can be multiple functions with the same name in the source code

  • In different classes and namespaces
  • Different overloads of the same function

There are also functions that don’t have a proper name – operators.
In the compiled code, functions must have unique names.
This mangling takes the form of creating a function name with some additional characters describing its return type and parameters.

Name mangling can create an issue when C code is mixed with C++.

When C code is compiled as C++, name mangling does not cause a problem because the compiler mangles the names of the C functions, and when the linker then links these with the C++ code calling them, it finds the names it expects.

When C code has been compiled as C, however, there is a problem, because the names in the compiled code will not be mangled, but the C++ trying to call it will be looking for mangled names.

The extern "C" directive instructs the compiler not to mangle the names of functions for linkage when reading their declaration, so functions compiled with a C compiler can be linked with C++.

There are 2 ways of using the extern "C" directive: before a declaration like this:

extern "C" int myfunc(const char *);

Or to define a block of declarations like this:

extern "C" {
int myfunc1(const char *);
int myfunc2(double);
// etc...
}

You can use these forms when you are writing the declarations in a header file or at the top of your C++ file knowing that they are going to be compiled by the C++ compiler.

If you need to include a C header in your code and can’t modify it, you can put an extern "C" directive around the #include as follows:

extern "C" {
#include <my-c-header.h>
}

So in summary:

  • You need to consider the effect of name mangling whenever you are mixing C and C++
  • C code compiled as C++ will not cause a problem
  • If you are writing the declarations for C code yourself, use extern "C" before each declaration or in a block around the declarations
  • If you are using an existing C header unchanged, put the #include for it in an extern "C" block

Reference: Decorated Names in the Visual Studio 2015 documentation