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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Почему я не могу throw объект типа ostringstream? 
:(
    Опции темы
mes
Дата 5.3.2010, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Dims @  5.3.2010,  21:15 Найти цитируемый пост)
Не могу согласиться. Язык не требует у меня, чтобы я в копирующем конструкторе наследника вызывал именно копирующий конструктор предка (а не какой-либо другой). 

Я полагаю, это высказывание основано на умозаключении что все конструкторы одинаковы. К сожалению это не так, и конструктор копий особый среди констукторов, а копирования рассматривается как отдельная тема.

Цитата(Dims @  5.3.2010,  21:15 Найти цитируемый пост)
По каким? Понимаете, дуть на воду я и сам умею. Назовите правило, которое я нарушил в своём примере.

12.8/14  smile
Цитата

12 Special member functions
12.8 Copying class objects
/1. A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&,
volatile X& or const volatile X&, and either there are no other parameters or else all other
parameters have default arguments (8.3.6).106) [Example: X::X(const X&) and X::X(X&, int=1)
are copy constructors.

/14. A program is ill-formed if the copy constructor or the copy assignment operator for an object is implicitly
used and the special member function is not accessible (clause 11 ( Member access control ) ).



Цитата(Dims @  5.3.2010,  21:15 Найти цитируемый пост)
Следовательно, если логика моей задачи позволяет в копирующем конструкторе инициализировать базовый класс по-другому, я могу это сделать и никакого жульничества тут нет. 

Следовательно :
Цитата(Dims @  5.3.2010,  21:15 Найти цитируемый пост)
Не могу согласиться.

smile


Это сообщение отредактировал(а) mes - 5.3.2010, 22:44


--------------------
PM MAIL WWW   Вверх
Dims
Дата 5.3.2010, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(mes @  5.3.2010,  22:44 Найти цитируемый пост)
Я полагаю, это высказывание основано на умозаключении что все конструкторы одинаковы.

Ошибочно полагаете. Это утверждение основано на том, что не возникает ошибки, если в копирующем конструкторе инициализировать базовый класс не копирующим, а другим конструктором.

Цитата(mes @  5.3.2010,  22:44 Найти цитируемый пост)
/14. A program is ill-formed if the copy constructor or the copy assignment operator for an object is implicitly
used and the special member function is not accessible (clause 11 ( Member access control ) ).

Мой случай под это не подпадает, так как я не использую неявно недоступную специальную функцию. Так что не убедили.

PM MAIL   Вверх
Lazin
Дата 5.3.2010, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



ваш конструктор копирования может бросить исключение во время раскрутки стека и завалить все приложение, теперь убедил? smile 
PM MAIL Skype GTalk   Вверх
Dims
Дата 5.3.2010, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Lazin @  5.3.2010,  23:27 Найти цитируемый пост)
ваш конструктор копирования может бросить исключение во время раскрутки стека и завалить все приложение

Это относится к любому конструктору копирования, а не только к моему. Вы же сами сказали: чтобы объект можно было бросать, у его класса должен быть конструктор копирования и оператор присваивания. Эти условия выполнены. Так какого же х..а? smile

Добавлено через 7 минут и 23 секунды
Поставим вопрос по другому: кто-нибудь может сказать, что именно в данный момент делает компилятор, что у него не выходит?

Вот по третьему примеру отсюда
http://forum.vingrad.ru/index.php?showtopi...t&p=2109551
я понимаю так:

компилятор создаёт объект A(), а затем пытается инициализировать a ссылкой на него; он видит, что конструктор по ссылке приватный и выдаёт ошибку.

Вот по этому примеру 
http://forum.vingrad.ru/index.php?showtopi...t&p=2110227
я понимаю так:

поскольку в классе B отсутствует копирующий конструктор, компилятор составляет его сам; там он пишет, мол, вызвать копирующий конструктор базового класса; а он у нас приватный приватный -- бац -- ошибка

Как можно подобным образом объяснить ошибку в моём случае?


PM MAIL   Вверх
Lazin
Дата 6.3.2010, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(Dims @  5.3.2010,  22:15 Найти цитируемый пост)
В чём же ошибка? Конструктор копирования у меня есть, присваивание у меня есть. Имею право throw-ить.

если есть, то имеете, но обращаться к закрытым членам класса это права не дает smile 
Цитата(Dims @  5.3.2010,  20:04 Найти цитируемый пост)
 error C2248


Цитата(Dims @  5.3.2010,  23:39 Найти цитируемый пост)
 Так какого же х..а? 

такого
Цитата(Lazin @  5.3.2010,  23:27 Найти цитируемый пост)
ваш конструктор копирования может бросить исключение во время раскрутки стека и завалить все приложение

у вас bad_alloc может быть брошено smile 
PM MAIL Skype GTalk   Вверх
mes
Дата 6.3.2010, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Dims @  5.3.2010,  22:26 Найти цитируемый пост)
Мой случай под это не подпадает, так как я не использую неявно недоступную специальную функцию. Так что не убедили.

Да Вы не используете, но 
Цитата

3.2./2. A copy constructor is used even if the call is actually elided by the implementation.

так что сжульничать не получится smile

Цитата(Dims @  5.3.2010,  22:39 Найти цитируемый пост)
Поставим вопрос по другому: кто-нибудь может сказать, что именно в данный момент делает компилятор, что у него не выходит?

если этот вопрос и теперь актуален, то  я могу в грубом примере пояснить что происходит 
smile

Это сообщение отредактировал(а) mes - 6.3.2010, 01:44


--------------------
PM MAIL WWW   Вверх
Dims
Дата 6.3.2010, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Lazin @  6.3.2010,  00:00 Найти цитируемый пост)
обращаться к закрытым членам класса это права не дает

Где я к ним обращаюсь, какой номер строки?

Цитата(mes @  6.3.2010,  00:10 Найти цитируемый пост)
A copy constructor is used even if the call is actually elided by the implementation

Не понимаю этой фразы.

Цитата(mes @  6.3.2010,  00:10 Найти цитируемый пост)
если этот вопрос после и теперь актуален,то  я могу в грубом примере пояснить что происходит 

Конечно, прошу Вас.

Добавлено через 14 минут и 5 секунд
Цитата(Lazin @  6.3.2010,  00:00 Найти цитируемый пост)
у вас bad_alloc может быть брошено

То есть, Вы дополняете свои первоначальные требования? Теперь их список таков:

1) класс должен иметь копирующий конструктор
2) класс должен иметь оператор присваивания
3) класс не должен мочь выбросить bad_alloc

так?

Вот контрпример, он компилируется, хотя условие 3 нарушено smile

Код

#include <stdlib.h>
#include <new>
using namespace std;

class A {

    int member;

public:
    A() { member = 0; }

    A(const A& ano) {
        member = ano.member;
        if( rand() < 100 ) throw bad_alloc();
    }

    A& operator=(const A& ano) {
        member = ano.member;
        if( rand() < 100 ) throw bad_alloc();
        return *this;
    }


};

int main() {
    A a;
    throw a;
}


PM MAIL   Вверх
Леопольд
Дата 6.3.2010, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Dims @  4.3.2010,  19:46 Найти цитируемый пост)
А как можно это обойти в данном случае?

Код
#include <iostream>

int main(){
    try{
        throw &std::cout;
    }
    catch(std::ostream* ex){
        (*ex)<<"test"<<std::endl;
    }
    
    return 0;
}


А так в общем случае:
Код
#include <iostream>
#include <boost/shared_ptr.hpp>

class C{
    C(const C&);
public:
    C() {}
    typedef boost::shared_ptr<C> SmartPtr;
};

int main(){
    try{
        throw C::SmartPtr(new C);
    }
    catch(C::SmartPtr&){
        std::cout<<"test"<<std::endl;
    }
    
    return 0;
}


Это сообщение отредактировал(а) Леопольд - 6.3.2010, 01:10


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 6.3.2010, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Dims @  5.3.2010,  23:50 Найти цитируемый пост)
Не понимаю этой фразы.

Конструктор копии используется даже тогда,  когда  реализация фактически обходит его использование.

Вот иллюстрация сказанного:
Код

// как реализован макрос мы условно не знаем :)
#define __CHECK_COPYABLE(cls) { sizeof  cls( *(A*)(NULL) ); }

struct A {

   A() { }

// private:
   A(const A&) {  }
};

struct B : A {

    B()  : A() {}

    B(const B&) : A() 
    { 
    // проверка на copyable, которая условно остается за пределами нашей видимости     
    // и находится естественно не в теле конструктора :)
            __CHECK_COPYABLE( A );
    }
};
int main (){ }


раскомментируйте "private:" для получения ошибки, не смотря на то что реализация  не использует конструктор копии класса А.

Добавлено @ 01:22
Цитата(Dims @  5.3.2010,  23:50 Найти цитируемый пост)
То есть, Вы дополняете свои первоначальные требования?

нет, пункт 3 не по теме.


Это сообщение отредактировал(а) mes - 6.3.2010, 01:42


--------------------
PM MAIL WWW   Вверх
Dims
Дата 6.3.2010, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(mes @  6.3.2010,  01:17 Найти цитируемый пост)
не смотря на то что реализация  не использует конструктор копии класса А.

Как же она его не использует, когда он используется в макросе __CHECK_COPYABLE? Я не вижу тут никакого неявного использования -- тут есть явное.

Цитата(mes @  6.3.2010,  01:17 Найти цитируемый пост)
// как реализован макрос мы условно не знаем smile

Ха! Ну и что, что мы не знаем? В макросе вызывается копирующий конструктор, его вызов присутствует, в него можно ткнуть пальцем. А ткните-ка пальцем, где копирующий конструктор базового класса используется в моём примере?

Цитата(mes @  6.3.2010,  01:17 Найти цитируемый пост)
Конструктор копии используется даже тогда,  когда  реализация фактически обходит его использование.

Почему тогда компилируется другой пример, где нет throw?

Добавлено через 5 минут и 8 секунд
Ха! А вот такой код:

Код

struct A {
   A() { }
 private:
   A(const A&) {  }
};

struct B : A {
    B()  : A() {}
    B(const B&) : A() {}
    B& operator=(const B&) {return*this;}
};

int main (){ 

    B b;
    throw b;
}



Работает. Проверил на VS и codepad: http://codepad.org/TViM3EQq
PM MAIL   Вверх
Lazin
Дата 6.3.2010, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(Dims @  6.3.2010,  00:50 Найти цитируемый пост)
A copy constructor is used even if the call is actually elided by the implementation

copy elision - это такая оптимизация, компилятор, в некоторых случаях может не копировать объект, передаваемый в качестве параметра или возвращаемый из функции, а использовать уже существующий

Цитата(Dims @  6.3.2010,  00:50 Найти цитируемый пост)
1) класс должен иметь копирующий конструктор
2) класс должен иметь оператор присваивания
3) класс не должен мочь выбросить bad_alloc

во первых не только bad_alloc, а любое исключение, во вторых, компилятор это никак не контролирует, просто твое приложение может упасть во время обработки какого-нибудь исключения

вообще, я не понимаю, почему не компилируется твой код, у меня нет под рукой компилятора, что-бы в этом разобраться, ясно только то, что происходит обращение к закрытому члену класса, где именно я не знаю
я бы на вашем месте, посмотрел на реализацию bsa, только унаследовал бы класс от std::exception
PM MAIL Skype GTalk   Вверх
Dims
Дата 6.3.2010, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Lazin @  6.3.2010,  10:45 Найти цитируемый пост)
copy elision - это такая оптимизация, компилятор, в некоторых случаях может не копировать объект, передаваемый в качестве параметра или возвращаемый из функции, а использовать уже существующий

А, ну это понятно: оптимизация никогда не должна сказываться на логике. 

Цитата(Lazin @  6.3.2010,  10:45 Найти цитируемый пост)
я бы на вашем месте, посмотрел на реализацию bsa, только унаследовал бы класс от std::exception 

Да  я уже давно написал при помощи агрегации; теперь мне просто интересно, почему так себя ведёт компилятор в данном случае.

PM MAIL   Вверх
Леопольд
Дата 6.3.2010, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(boost.org)
 The Boost Exception library supports transporting of arbitrary data in exception objects, and transporting of exceptions between threads.



--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 6.3.2010, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Dims @  6.3.2010,  08:23 Найти цитируемый пост)
Как же она его не использует, когда он используется в макросе __CHECK_COPYABLE? 

так о том и речь :

Цитата(mes @  6.3.2010,  00:17 Найти цитируемый пост)

A copy constructor is used even if the call is actually elided by the implementation
Конструктор копии используется даже тогда,  когда  реализация фактически обходит его использование.


Наша реализация обходит использование копи-конструктора,  но он все равно используется компилятором.
т.е несмотря на программисту не нужен, компилятор его проверяет.

Цитата(Dims @  6.3.2010,  08:23 Найти цитируемый пост)
 В макросе вызывается копирующий конструктор, его вызов присутствует, в него можно ткнуть пальцем.

Ну-ка ткните пальцем  smile  Никакого вызова копи-конструктора макросом не происходит, только проверяется его доступность.   smile 

Цитата

5.3.3 Sizeof
... The operand is either an expression, which is not evaluated,...


Это сообщение отредактировал(а) mes - 6.3.2010, 12:56


--------------------
PM MAIL WWW   Вверх
mes
Дата 6.3.2010, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Dims @  6.3.2010,  08:23 Найти цитируемый пост)
Работает. Проверил на VS и codepad: http://codepad.org/TViM3EQq 

компилируется не значит работает smile стандарт не запрещает компилировать, он лишь сообщает о том что такая программа ill-formed 
smile

еще раз для закрепления  :
Цитата

12.8/14 A program is ill-formed if the copy constructor or the copy assignment operator for an object is implicitly
used and the special member function is not accessible

1.3.4 ill-formed program - input to a C + + implementation that is not a well-formed program (1.3.14).

1.3.14 well-formed program - a C + + program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition
Rule (3.2).

3.2/2 A copy constructor is used even if the call is actually elided by the implementation.

smile
и вообще некрасиво разрешать наследнику копирование, когда открытая база запрещает.. нарушение логики при приведении.


Это сообщение отредактировал(а) mes - 6.3.2010, 14:45


--------------------
PM MAIL WWW   Вверх
Страницы: (4) Все 1 2 [3] 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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