Предотвращение построения путем создания исключения перед телом конструктора

C ++

Я хочу урок throw исключение перед открывающей фигурной скобкой тела его конструктора { используя собственную функцию-член для предотвращения строительства. Я определил функцию-член, целью которой является только безоговорочное throw исключение, с произвольно выбраннымvoid возвращаемый тип и фиктивный член данных, тип которого соответствует этому возвращаемому типу, так что я могу вызвать throw путем создания этого члена данных с помощью вызова указанной функции-члена в списке инициализатора конструктора. Это работает, но не элегантно, потому что в не игрушечном классе фиктивная переменная не будет служить никакой другой цели, кроме как оправдание для запуска функции-члена, а функция-члена неvoid возвращаемый тип не служит никакой другой цели, кроме как иметь оправдание для его вызова конструктором фиктивного члена данных того же типа.

Эта игрушка компилируется, но не элегантна:

class Toy
{
public:
Toy() : dummy(preventer()) {}
private:
int dummy;
int preventer() {throw -1; return 0;}
};

#include <iostream>

int main()
{
try
{
Toy t;
}
catch (const int& e)
{
std::cout << "caught the exception\n";
}
return 0;
}

Консольный вывод:

caught the exception

Без фиктивной переменной есть ли способ выбросить исключение перед открывающей фигурной скобкой { тела конструктора?

0

Решение

Вы можете избежать фиктивного возвращаемого значения функции следующим образом:

bool called = (function(), true);

Оператор запятой между двумя выражениями справа вычисляет выражения по очереди, отбрасывая все, кроме последнего результата. Что меня интересует, так это то, почему вы настаиваете на том, чтобы сделать это до открытия фигурных скобок. Что именно вы пытаетесь достичь здесь, чего вы не можете достичь с помощью вызова функции как первой вещи в теле?

Обратите внимание, что если вы хотите прервать работу как можно раньше, лучше всего сделать это в отдельном базовом классе (вы можете использовать частное наследование). Это единственное решение, которое позволяет вам предотвратить даже создание других баз, чего нет в вашем решении.

1

Другие решения

Да, вы можете использовать базовый класс вместо члена данных, а затем вызывать конструктор базового класса.

Обратите внимание, что старые версии отладчика GNU gdb (несколько лет назад) не смог взломать такое исключение.

Тем не менее, работает нормально с Visual C ++, и я верю также с современными версиями инструментария GNU.

2