2013-03-28 4 views
0

C++Предотвращение строительства, бросая исключение, прежде чем конструктор тело

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

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

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 

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

+1

посмотреть эту тему: http://stackoverflow.com/questions/2672398/throw-exception-from-constructor-initializer? – taocp

+0

@ Ken White, я не пытаюсь создать синглтон в частности. Я просто хочу знать, как предотвратить строительство до тела конструктора, в общем. – CodeBricks

+0

Получил это. :-) Я видел ссылку, которую @SongWang опубликовал и удалил мой комментарий; должно быть, произошло так же, как вы ответили. –

ответ

1

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

bool called = (function(), true); 

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

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

+0

Чтобы ответить на ваш вопрос: я стараюсь предотвратить строительство как можно скорее, а не в корпусе ctor по соображениям производительности. Я хочу предотвратить строительство в определенных случаях использования.В этих случаях я хочу предотвратить строительство, прежде чем дорогие члены данных будут построены по очереди. – CodeBricks

+0

В этом случае конструктор первого базового слоя будет хорошим местом. Тем не менее, я не уверен, что ваш подход - это ound. Выделение памяти и обработка исключения - дорогостоящая операция, поэтому я бы скорее избежал этого. Это ваше решение. Удачи! –

+0

Я предполагаю, что ваш 'bool called = (function(), true);' метод с запятой является частью инициализатора элемента данных в классе. Есть ли способ сделать это в инициализаторе ctor? – CodeBricks

2

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

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

Однако, работает нормально с Visual C++, и я также верю в современные версии инструментальной цепочки GNU.

+0

+1, хороший ответ, и спасибо. Дал голосование, но я должен выбрать ответ, чтобы принять, и принятый ответ дает дополнительное решение в дополнение к наследованию. – CodeBricks