2013-03-11 2 views
-2

ScreenShot # 1: Sample (Образец &) {...) // Нет ошибки без использования "сопзЬ" enter image description here ScreenShot # 2: Деструктор вызывается дважды, когда копия-конструктор не включено. enter image description hereКонструкторы ведут себя странно с кодом обработки исключений

Когда я запускаю этот код в VC++ 2010, я нашел результаты surprizing, пожалуйста, посмотрите:

#include <iostream> 
using namespace std; 

class Sample { 
public: 
    Sample() { cout<<"Sample().\n"; } 
    // Sample (Sample&) { cout<<"Sample(Sample&).\n"; } 
    ~Sample() { cout<<"~Sample().\n"; } 
}; 

void fx() { 
    throw Sample(); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    try { fx(); } 
    catch (Sample&) { cout<<"Caught Sample.\n"; } 
    return 0; 
} 

Пожалуйста скажите, почему не включая копировать-конструктор в примере, деструктор вызывается дважды , И поэтому вызывает Abort(), если мы, например, освобождаем кучу в деструкторе.

Также я знаю, что экземпляр объекта создается из объекта метания, но почему он не вызывает для него экземпляр-конструктор.

См. Прилагаемый скриншот для кода и вывода.

+0

Во-первых, это должен быть 'class Sample {' not 'class Sample() {'. – 2013-03-11 04:45:14

+0

Кроме того, конструктор копирования должен взять ссылку на const, или вы получите ошибку компилятора. – 2013-03-11 04:48:00

+0

Можете ли вы показать нам свой реальный код? Когда я компилирую и запускаю это, я вижу только «Sample() - Caught_Sample - ~ Sample -'. (с конструктором копирования и без него) – Xymostech

ответ

2

Это, кажется, ошибка (функция? :)) в компиляторе VC++, который был вокруг на некоторое время (у меня нет никаких ссылок для поддержки этого утверждения напрямую, но у меня нет времени для продолжения поиска Я думаю, что я наткнулся на это один или два раза.) Это все еще происходит в VC++ 2012.

Это хорошая практика кодирования, которая всегда определяет копию ctor, даже если вы ее не используете. Это часть The Rule of Three. Однако есть оговорки.

  1. VC++ будет использовать контекст объекта, а не вызывающего, при попытке выполнить копию ctor при метании. Поэтому, даже если он будет закрыт, он все равно будет доступен. Это, вероятно, наследие, хотя я не могу найти ничего конкретного.

  2. VC++ разрешает копирование ctor с неконстантным параметром при метании. Это также наследие, позволяющее перемещать ресурсы вокруг до внедрения парадигмы движения. Я только нашел несколько вещей, смутно уклоняющихся от этого. И нет, VC++, похоже, не использует парадигму перемещения для бросания объектов, поэтому это происходит, если вы попытаетесь реализовать конструктор перемещения.

Для получения дополнительной информации о конструкторе перемещения вы можете найти here.

Обратите внимание, что Microsoft, похоже, вишня выбирает, какую часть стандарта C++ она реализует, основываясь на том, что она сломает слишком много вещей. По этой причине я не думаю, что хочу быть в команде разработчиков компилятора в M $. :/

+0

Отклонено ли это отклонение от стандартного документа? – 2013-03-11 21:13:45

Смежные вопросы