Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Unhandled exception 
:(
    Опции темы
User008
Дата 6.5.2012, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Код

#include <memory>
#include <stdio.h>

class X
{
public:
    virtual void f() { printf("X::f"); }
};

class XD : public X
{
public:
    virtual void f() { printf("XD::f"); }
    virtual void ff() { printf("XD::ff"); }
};

class Y
{
public:
    Y() { x = std::auto_ptr<X>(makeX()); }
    virtual void f() { printf("Y::f"); }
protected:
    virtual X *makeX() const { return new X; }
    std::auto_ptr<X> x;
};

class YD : public Y
{
public:
    virtual void f() { printf("YD::f"); }
    virtual void ff() { printf("YD::ff"); ((XD *)x.get())->ff(); }
protected:
    virtual X *makeX() const { return new XD; }
};

int main()
{
    try {
        YD yd;
        yd.ff();
    }
    catch(...) {
        printf("Exception");
    }
}

((XD *)x.get())->ff(); при выполнении этого возникает некий exception, который даже в catch не попадает. Что происходит?

Это сообщение отредактировал(а) User008 - 6.5.2012, 16:28
PM MAIL   Вверх
User008
Дата 6.5.2012, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Если убрать virtual из XD::ff, то исключение не бросается. Не понимаю, что происходит.
PM MAIL   Вверх
borisbn
Дата 6.5.2012, 17:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



а с чего ради 
Цитата
((XD *)x

икс ( вернее x.get() )должен приводиться к XD *?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
User008
Дата 6.5.2012, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Цитата(borisbn @  6.5.2012,  17:39 Найти цитируемый пост)
а с чего ради 
икс ( вернее x.get() )должен приводиться к XD *? 

Чтобы работать с ним как с указателем на объект класса XD - в данном примере, чтобы вызвать метод ff.

Это сообщение отредактировал(а) User008 - 6.5.2012, 17:54
PM MAIL   Вверх
Randajad
Дата 6.5.2012, 19:55 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Видимо в конструкторе недопустимо использовать виртуальные функции. smile

Это сообщение отредактировал(а) Randajad - 6.5.2012, 20:03
PM MAIL   Вверх
Sahab
Дата 7.5.2012, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Откройте для себя dynamic_cast...
http://liveworkspace.org/code/4eae1505583c...e631626a517ba6e

Добавлено через 4 минуты и 49 секунд
Да... и segfault != exception

Это сообщение отредактировал(а) Sahab - 7.5.2012, 00:35
PM MAIL   Вверх
baldina
Дата 7.5.2012, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(User008 @  6.5.2012,  16:10 Найти цитируемый пост)
некий exception, который даже в catch не попадает

обращение по неверному адресу не родит исключение. ну если только компилятор+его настройки это не делают, но это нестандартно.
Цитата(Sahab @  7.5.2012,  00:32 Найти цитируемый пост)
Откройте для себя dynamic_cast

лучше откройте для себя фабрику
PM MAIL   Вверх
User008
Дата 7.5.2012, 03:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Цитата(baldina @  7.5.2012,  00:44 Найти цитируемый пост)
лучше откройте для себя фабрику 

Я думал то, что я написал и есть фабричный метод.
PM MAIL   Вверх
User008
Дата 7.5.2012, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Посмотрел примеры с фабричным методом. В тех, что я видел класс поля выбирается через параметр базового класса. А что если я не хочу делать базовый класс зависимым от классов, которые будут использованы в производных?

Это сообщение отредактировал(а) User008 - 7.5.2012, 10:35
PM MAIL   Вверх
xvr
Дата 7.5.2012, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



В вашей 'фабрике' вызов метода фабричного метода makeX делается в конструкторе, а там виртуальность не работает (т.е. ваша фабрика всегда будет порождать класс X), о чем вам Randajad тонко намекнул  smile 
PM MAIL   Вверх
User008
Дата 7.5.2012, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Цитата(xvr @ 7.5.2012,  11:25)
В вашей 'фабрике' вызов метода фабричного метода makeX делается в конструкторе, а там виртуальность не работает (т.е. ваша фабрика всегда будет порождать класс X), о чем вам Randajad тонко намекнул  smile

Да, спасибо, я это понял. А как сделать, чтобы при создании объекта поле становилось возвращаемым значением makeX?
PM MAIL   Вверх
baldina
Дата 7.5.2012, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(User008 @  7.5.2012,  10:34 Найти цитируемый пост)
если я не хочу делать базовый класс зависимым от классов, которые будут использованы в производных

то вы пишете функцию (или класс Фабрика), которая осведомлена о Ваших подклассах. Базовый, как правило, не знает, да и не должен
PM MAIL   Вверх
borisbn
Дата 8.5.2012, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Вот пару вариантов
Код

template< class T = X >
class Y
{
public:
    Y() { x = std::auto_ptr<X>(makeX()); }
    virtual void f() { printf("Y::f"); }
protected:
    virtual X *makeX() const { return new T; }
    std::auto_ptr<X> x;
};

class YD : public Y< XD>
{
public:
    virtual void f() { printf("YD::f"); }
    virtual void ff() {
       printf("YD::ff");
       XD *xd = dynamic_cast<XD *>(x.get());
       if(xd)
          xd->ff();  
    }
};


Код

typedef std::function< X*() > makeX_t;

class Y
{
public:
    Y( makeX_t makeX ) { x = std::auto_ptr<X>(makeX()); }
    virtual void f() { printf("Y::f"); }
protected:
    std::auto_ptr<X> x;
};

class YD : public Y
{
public:
    YD() : Y( [](){ return new XD; } ) {}
    virtual void f() { printf("YD::f"); }
    virtual void ff() {
       printf("YD::ff");
       XD *xd = dynamic_cast<XD *>(x.get());
       if(xd)
          xd->ff();  
    }
};

http://liveworkspace.org/code/659da452574b...d7a462d8403f101


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
User008
Дата 8.5.2012, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 306
Регистрация: 9.9.2009

Репутация: 1
Всего: 1



Я правильно понимаю, что если класс делается шаблонным, то его определения должны быть написаны в хедере, соответственно в тех файлах, в которых подключается этот хедер, его определения будут дублироваться?

Это сообщение отредактировал(а) User008 - 8.5.2012, 14:55
PM MAIL   Вверх
baldina
Дата 8.5.2012, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



да. шаблонный класс должен быть определен в каждой единице компиляции (кроме extern, но эта фича пока мало поддерживается)
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0594 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.