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
Без фиктивной переменной есть ли способ выбросить исключение перед открывающей фигурной скобкой {
тела конструктора?
Вы можете избежать фиктивного возвращаемого значения функции следующим образом:
bool called = (function(), true);
Оператор запятой между двумя выражениями справа вычисляет выражения по очереди, отбрасывая все, кроме последнего результата. Что меня интересует, так это то, почему вы настаиваете на том, чтобы сделать это до открытия фигурных скобок. Что именно вы пытаетесь достичь здесь, чего вы не можете достичь с помощью вызова функции как первой вещи в теле?
Обратите внимание, что если вы хотите прервать работу как можно раньше, лучше всего сделать это в отдельном базовом классе (вы можете использовать частное наследование). Это единственное решение, которое позволяет вам предотвратить даже создание других баз, чего нет в вашем решении.
Да, вы можете использовать базовый класс вместо члена данных, а затем вызывать конструктор базового класса.
Обратите внимание, что старые версии отладчика GNU gdb
(несколько лет назад) не смог взломать такое исключение.
Тем не менее, работает нормально с Visual C ++, и я верю также с современными версиями инструментария GNU.