> ## Content Index
> Fetch the complete content index at: https://www.smallstepsystems.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Emitting Signals during Construction or Destruction
- URL: https://www.smallstepsystems.com/emitting-signals-during-construction-or-destruction/
- Published: 2018-10-02T16:58:20.000Z
- Updated: 2026-01-25T15:46:37.000Z
- Author: Burkhard Stubert

![](https://storage.ghost.io/c/c7/ee/c7ee1cf5-b86f-491b-aab7-20ad081598e1/content/images/2025/11/emittingsignalsinctorsdtors.png)

In the beginning, the application shows the *Main Screen*. When the user clicks on the *Open* button, the application will show a second screen. The second screen creates a C++ model when opened and destroys this model when closed.

As zealous Qt developers, we use the [pimpl idiom](https://herbsutter.com/gotw/%5F100/?ref=smallstepsystems.com) to hide private declarations from its clients. Hence, we move the write and read functions of Qt properties to the implementation class in the source file. When the value of the property changes, the write function emits a signal of the interface class.

When the signal emission occurs during the construction or destruction of the interface class, we end up in the land of undefined behaviour. At the point of the signal emission, the interface object does not exist yet or does not exist any more. A real-life application will most likely crash - right a way if we are lucky or much later if Old Murphy has his way.

### Setting Things Up

We define a property in the header file `Model.h` of the interface class `Model`:

Q\_PROPERTY(QString infoText READ infoText WRITE setInfoText NOTIFY infoTextChanged)

The read and write functions just forward the calls to the implementation class `Model::Impl`.

QString Model::infoText() const { return m\_impl->infoText(); } void Model::setInfoText(const QString &text) { m\_impl->setInfoText(text); }

The implementation class provides the implementation of the read and write functions.

QString Model::Impl::infoText() const { return m\_infoText; } void Model::Impl::setInfoText(const QString &text) { if (m\_infoText != text) { qDebug() << \_\_PRETTY\_FUNCTION\_\_; m\_infoText = text; emit m\_iface->infoTextChanged(); } }

As usual, the write function emits a signal, if the value of the property `infoText` changes. The unusual thing is that the implementation class emits a signal of the interface class. Note the use of `m_iface` when emitting the signal. The member variable `m_iface` contains a pointer back to the interface object.

### Emitting Signals during Construction

The constructors of the interface class `Model` and of the implementation class `Model::Impl` look as follows.

Model::Model(QObject \*parent) : QObject{parent}, m\_impl{new Impl{this}} { qDebug() << \_\_PRETTY\_FUNCTION\_\_; } Model::Impl::Impl(Model \*parent) : QObject(parent), m\_iface(parent), m\_infoText{QStringLiteral("Waiting...")} { qDebug() << \_\_PRETTY\_FUNCTION\_\_; setInfoText("Constructor: Oooops!!!"); }

The example code contains debugging outputs so that we easily see in which order functions are called. The trace for the construction of the `Model` object looks as follows.

Model::Impl::Impl(Model \*) void Model::Impl::setInfoText(const QString &) // Undefined!!! Model::Model(QObject \*)

The initialisation order of classes, its base classes and its data members is defined in §15.6.2/(13) \[class.base.init\] of the [C++17 Standard](https://www.iso.org/standard/68564.html?ref=smallstepsystems.com). When the QML component `SecondScreen` calls the `Model` constructor, the following steps occur.

1. The non-static data members of the interface class `Model` are initialised first. So, `Model::m_impl` is initialised, which results in the call of the constructor of the implementation class: `Model::Impl::Impl(Model *)`.
2. The constructor of the implementation class initialises its data members: `m_iface` and `m_infoText`. Then, it executes its body, which results in calling `void Model::Impl::setInfoText(const QString &)`.
3. Then, it is time to execute the body of the `Model` constructor: `Model::Model(QObject *)`.

According to §6.8/(1.1-1.2) \[basic.life\], the lifetime of the `Model` object begins when its initialisation is complete. This is only true after step 3\. When the function `Model::Impl::setInfoText` calls the signal `infoTextChanged` on the `Model` object `m_iface` in step 2, this object does not exist yet. The behaviour of emitting the signal is undefined.

### Emitting Signals during Destruction

The destructors of the interface class `Model` and of the implementation class `Model::Impl` look as follows.

Model::\~Model() { qDebug() << \_\_PRETTY\_FUNCTION\_\_; } Model::Impl::\~Impl() { qDebug() << \_\_PRETTY\_FUNCTION\_\_; setInfoText("Destructor: Oooops!!!"); }

The `Model` object is destroyed in the reverse order of its construction as the C++17 Standard (see note after §15.6.2/(13)) mandates and the trace shows.

virtual Model::\~Model() virtual Model::Impl::\~Impl() void Model::Impl::setInfoText(const QString &) // Undefined!!!

When `SecondScreen` calls the destructor of the `Model` object, the following steps occur.

1. The body of the destructor `Model::~Model()` is executed.
2. The non-static data members of `Model` are destroyed, which results in calling `Model::Impl::~Impl()`.
3. The body of `Model::Impl::~Impl()` is executed, which results in calling `void Model::Impl::setInfoText(const QString &)`.
4. Finally, the non-static data members of the implementation class are destroyed.

According to §6.8/(1.3-1.4) \[basic.life\], the lifetime of the `Model` object ends, when its destructor is called. This happens in step 1\. When the function `Model::Impl::setInfoText` calls the signal `infoTextChanged` on the `Model` object `m_iface` in step 2, this object does not exist any more. Hence, the behaviour of emitting the signal is undefined.

### How to Fix

A fix must satisfy the following rule: The constructor and the destructor of the implementation class must not call member functions of the interface class. Corollary: They must not emit signals of the interface class. The interface object does not exist yet or does not exist any more.

An easy fix is to call `Model::setInfoText` in the body of the constructor or in the body of the destructor of the interface class `Model`. The trace for the construction looks like this:

Model::Impl::Impl(Model \*) Model::Model(QObject \*) void Model::setInfoText(const QString &) void Model::Impl::setInfoText(const QString &)

In step 3, the `Model` constructor calls its own member function `Model::setInfoText`, which is perfectly legal C++ code according to §15.7/(3) of the C++17 Standard. The implementation object `Model::Impl` has been fully constructed at this point. So, `Model::setInfoText` can call `Model::Impl::setInfoText`, which can call `Model::infoTextChanged` without any problems.

The trace for the destruction is reversed:

virtual Model::\~Model() void Model::setInfoText(const QString &) void Model::Impl::setInfoText(const QString &) virtual Model::Impl::\~Impl()

In step 3, the `Model` destructor calls its own member function `Model::setInfoText`. At this point, the `Model::Impl` still exists so that the call to `Model::Impl::setInfoText` by `Model::setInfoText` is perfectly OK.

### Getting the Example Code

The code is available on [Github](https://github.com/bstubert/embeddeduse/tree/master/BlogPosts/EmittingSignalsInConstructorsOrDestructors?ref=smallstepsystems.com). You can try out the fix by uncommenting

//#define PROBLEM\_FIXED

at the beginning of the file *Model.cpp*.