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

Поиск:

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


Эксперт
***


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

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



Почему такой код

Код

#include <sstream>
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    ostringstream o;
    throw o;
}


вызывает такие ошибки

Error    1    error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'    c:\program files\microsoft visual studio 9.0\vc\include\sstream    451    Test_ostringstream
Error    2    error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'    c:\program files\microsoft visual studio 9.0\vc\include\ostream    584    Test_ostringstream

?

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


Эксперт
****


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

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



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


Эксперт
***


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

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



А как можно это обойти в данном случае?

И почему я могу throw-ить произвольный свой класс без таких операторов?

Вот так работает:

Код

#include <sstream>
using namespace std;

class A {

    int value;
};



int _tmain(int argc, _TCHAR* argv[])
{
    ostringstream o;
    A a;

    //throw o;
    throw a;
}

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


Опытный
**


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

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



А можно через проверку?
Код

if( o. ...... )  //проверить что-то
     throw "Some error";

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


Кодофей
****


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

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



Цитата(TGrey @  4.3.2010,  19:57 Найти цитируемый пост)
А можно через проверку?

можно.



--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
mes
Дата 4.3.2010, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  4.3.2010,  18:46 Найти цитируемый пост)
И почему я могу throw-ить произвольный свой класс без таких операторов?

потому что у исключения другое время жизни, нежели у переменной определенной в блоке,
ну а чтоб задать новую длину жизни необходимо уметь копировать его, о чем и сказано в цитате Lazin`a
 smile

Цитата(Dims @  4.3.2010,  18:46 Найти цитируемый пост)
Вот так работает:

Потому что имеются нужные операторы .. некоторые операторы добавляются скрыто в случае если не определены программистом..
те что требуются относятся к числу подобных.




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


Эксперт
***


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

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



Непонятно.


Во-первых, какими образом и с какой целью достигнуто, чтобы ostringstream нельзя было копировать?

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

Код

int _tmain(int argc, _TCHAR* argv[])
{
    ostringstream o;
    ostringstream o1;
    
    o1 = ostringstream(o);
    

    // throw o;
    // throw a;
}

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


Эксперт
****


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

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



Цитата(Dims @  4.3.2010,  19:46 Найти цитируемый пост)
И почему я могу throw-ить произвольный свой класс без таких операторов?

потому что компилятор, заботливо делает это за тебя
PM MAIL Skype GTalk   Вверх
mes
Дата 4.3.2010, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  4.3.2010,  19:02 Найти цитируемый пост)
Во-первых, какими образом .. чтобы ostringstream нельзя было копировать?

компилятор же говорит :
Цитата(Dims @  4.3.2010,  14:09 Найти цитируемый пост)
: cannot access private member



Цитата(Dims @  4.3.2010,  19:02 Найти цитируемый пост)
и с какой целью достигнуто, 

для того чтоб исключить возможное копирование smile

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

Цитата(Dims @  4.3.2010,  19:02 Найти цитируемый пост)
Во-вторых, почему тогда вот это компилируется нормально:

а это вопрос к VS  smile 


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


Эксперт
****


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

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



Dims, а ты попробуй такой код:
Код
class A
{
   A(const A&);
public:
   A(){}
};

int main()
{
   A a;
   throw a;
}
и такой:
Код
class A
{
   A(const A&);
public:
   A(){}
};

int main()
{
   A a;
   A b;
   a = b;
}
И еще такой:
Код
class A
{
   A(const A&);
public:
   A(){}
};

int main()
{
   A a = A();
}
И попробуй объяснить результат.

Это сообщение отредактировал(а) bsa - 5.3.2010, 01:09
PM   Вверх
mes
Дата 4.3.2010, 20:42 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(bsa @  4.3.2010,  19:38 Найти цитируемый пост)
И попробуй объяснить результат. 

чтоб можно было начать объяснять результаты, надо ко всем классам имеющим закрытый констуктор копий добавить открытый конструктор по умолчанию.
 smile 



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


Эксперт
****


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

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



Цитата(mes @  4.3.2010,  20:42 Найти цитируемый пост)
надо ко всем классам имеющим закрытый констуктор копий добавить открытый конструктор по умолчанию.
исправил. спасибо. (стормозил, писал и думал, что что-то забыл  smile )

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


Эксперт
***


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

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



Цитата(bsa @  4.3.2010,  20:38 Найти цитируемый пост)
Dims, а ты попробуй такой код:


Первый пример: ругается линкер: Error    1    error LNK2001: unresolved external symbol "private: __thiscall A::A(class A const &)" (??0A@@AAE@ABV0@@Z)    Test_ostringstream.obj    Test_ostringstream


Ошибка понятна: конструктор объявлен, вызывается, но не определён.

Второй пример: не ругается. Понятно: хотя конструктор не определён, но он и не используется.

Третий пример: ругается компилятор: Error    1    error C2248: 'A::A' : cannot access private member declared in class 'A'

А какое это имеет отношения к моему примеру?

Добавлено через 3 минуты и 28 секунд
Ребят, скажите пожалуйста, откуда вообще всплыла эта тема? 

Судя по моей проверке вот тут: http://forum.vingrad.ru/index.php?showtopi...t&p=2109522

В классе ostringstream присутствуют и доступны как конструктор копирования по ссылке, так и оператор присваивания. Поэтому почему вы думаете, что дело в их отсутствии?
PM MAIL   Вверх
mes
Дата 5.3.2010, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  5.3.2010,  15:53 Найти цитируемый пост)
А какое это имеет отношения к моему примеру?    

неужто не замечаете сходства ?

Цитата(Dims @  4.3.2010,  14:09 Найти цитируемый пост)
 error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member ...

Цитата(Dims @  5.3.2010,  15:53 Найти цитируемый пост)
 error C2248: 'A::A' : cannot access private member declared in class 'A'

 smile 


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


Эксперт
***


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

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



Действительно, на Юниксе мой пример не компилируется...

Добавлено через 1 минуту и 20 секунд
Цитата(mes @  5.3.2010,  16:57 Найти цитируемый пост)
неужто не замечаете сходства ?

Я не замечаю сходства в коде, который вызвал эту ошибку. Код со throw вызвал другую.
PM MAIL   Вверх
bsa
Дата 5.3.2010, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Dims @  5.3.2010,  17:08 Найти цитируемый пост)
Код со throw вызвал другую. 
А если так:
Код
class A
{
   A(const A&);
public:
   A(){}
};

class B : public A
{
public:
   B(){}
};

int main()
{
   B b;
   throw b;
}

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


Эксперт
***


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

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



Написал нижеследующим образом и получаю всё равно такую же ошибку. Почему?

Код

#include <sstream>
using namespace std;


class A : public ostringstream {

public:
    int myMember;

    A() : ostringstream() {
    }

    A(const A& proto) : ostringstream() {
        (*this) << ((ostringstream *)(&proto))->str();
    }

    A& operator=(const A& proto) {
        str("");
        (*this) << ((ostringstream *)(&proto))->str();
        return *this;
    }

};


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



Добавлено через 6 минут и 23 секунды
Цитата(bsa @  5.3.2010,  17:20 Найти цитируемый пост)
А если так:


Да, так похоже.

Кое-что проясняется: ошибка возникает в коде, который генерирует сам компиллятор. 

Но понятно не всё smile

Почему мой 2-й пример компилируется? Ладно, это особенности ВС.

А почему мой последний не компилируется? Ведь я, вроде, написал что ему надо.
PM MAIL   Вверх
bsa
Дата 5.3.2010, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код
(*this) << ((ostringstream *)(&proto))->str();
Ржунимагу...
Почему нельзя написать так?
Код
*this << proto.str();


И вообще, наследовать подобные классы не есть хорошо. лучше использовать агрегацию:
Код
class A
{
   A() {}
   A(const A &a) { stream_.str( a.stream_.str() ); }
   A& operator=(const A &a) {
       stream_.str( a.stream_.str() );
       return *this;
   }
   template<class T>
   friend A& operator<<(A &a, T v) {
        a.stream_ << v;
        return a;
   }
private:
   std::ostrinstream stream_;
};
Цитата
Написал нижеследующим образом и получаю всё равно такую же ошибку. Почему?
У меня проблем этого кода с компиляцией нет.
PM   Вверх
mes
Дата 5.3.2010, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  5.3.2010,  16:23 Найти цитируемый пост)

А почему мой последний не компилируется? Ведь я, вроде, написал что ему надо. 

причина имеет те же корни smile

Цитата(Dims @  5.3.2010,  16:23 Найти цитируемый пост)
А почему мой последний не компилируется? Ведь я, вроде, написал что ему надо. 

 smile 
может немножко помягче написать то же самое : http://codepad.org/yuAzPD23 ?

Добавлено через 59 секунд
Цитата(bsa @  5.3.2010,  16:43 Найти цитируемый пост)
И вообще, наследовать подобные классы не есть хорошо. лучше использовать агрегацию:

а bsa уже сказал оказывается smile

Добавлено через 2 минуты и 21 секунду
Цитата(bsa @  5.3.2010,  16:43 Найти цитируемый пост)
У меня проблем этого кода 

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


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


Эксперт
***


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

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



Цитата(bsa @  5.3.2010,  17:43 Найти цитируемый пост)
У меня проблем этого кода с компиляцией нет. 

Какого кода и на какой системе?

Цитата(mes @  5.3.2010,  17:49 Найти цитируемый пост)
причина имеет те же корни


Те же корни -- это какие?

Вот этих

Цитата(Lazin @  4.3.2010,  15:30 Найти цитируемый пост)
исключение должно иметь конструктор копирования и оператор присваивания 


корней больше нет.

Цитата(mes @  5.3.2010,  17:49 Найти цитируемый пост)
ожет немножко помягче написать то же самое

Цитата(bsa @  5.3.2010,  17:43 Найти цитируемый пост)
наследовать подобные классы не есть хорошо. лучше использовать агрегацию


Это понятно. Вопрос уже в теории: почему не компилируется код?

Добавлено через 5 минут и 42 секунды
Да, бред какой-то. На Виндах не компилируется, а на Линуксе компилируется.
PM MAIL   Вверх
mes
Дата 5.3.2010, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  5.3.2010,  17:15 Найти цитируемый пост)
Вопрос уже в теории: почему не компилируется код?

приведите сообщение об ошибке .. интуитивно полагаю, что проблема в 
Цитата(mes @  5.3.2010,  16:49 Найти цитируемый пост)
 раскрытии закрытого конструктора копии

а точнее в том, как это действие интерпретирует Ваш компилятор.

Цитата(Dims @  5.3.2010,  17:15 Найти цитируемый пост)
исключение должно иметь конструктор копирования и оператор присваивания 
корней больше нет.

А вы уверены что  Вы освободили эти корни smile, в общем для начала ошибку в студию.

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


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


Эксперт
***


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

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



Ниже сообщение. Возникает ДВЕ ошибки:

Error    1    error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'    C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sstream    451    Test_ostringstream2
Error    2    error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'    C:\Program Files\Microsoft Visual Studio 9.0\VC\include\ostream    584    Test_ostringstream2

Код такой:

Код

// Test_ostringstream2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "stdafx.h"

#include <sstream>
#include <iostream>

using namespace std;

class A : public ostringstream {

public:
    int myMember;

    A() : ostringstream() {
    }

    A(const A& proto) : ostringstream() {
        (*this) << ((ostringstream *)(&proto))->str();
    }

    A& operator=(const A& proto) {
        str("");
        (*this) << ((ostringstream *)(&proto))->str();
        return *this;
    }

};


int main() {
    A a;
    cout << "Hello!" << endl;
    throw a;
}



Добавлено через 3 минуты и 20 секунд
О, чё на сайте говорит: http://codepad.org/8pIjcxuu
PM MAIL   Вверх
Lazin
Дата 5.3.2010, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



ostringstream не предназначен для наследования
использовать в качестве исключений, нужно классы - наследники std::exception, иначе будет невозможно в одном catch обрабатывать любые исключения, а так-же, если в конструкторе копирования вашего исключения будет брошено другое исключение - будет вызвана ф-я terminate
у basic_ios, скорее всего закрытый конструктор копирования, что не удивительно, поэтому ваш код не компилируется
PM MAIL Skype GTalk   Вверх
Dims
Дата 5.3.2010, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Lazin @  5.3.2010,  20:11 Найти цитируемый пост)
у basic_ios, скорее всего закрытый конструктор копирования, что не удивительно, поэтому ваш код не компилируется 

На Линуксе мой код компилируется:

Код

[dims@testbed cpptests]$ cat test03.cpp
#include <sstream>
#include <iostream>

using namespace std;

class A : public ostringstream {

public:
    int myMember;

    A() : ostringstream() {
    }

    A(const A& proto) : ostringstream() {
        (*this) << ((ostringstream *)(&proto))->str();
    }

    A& operator=(const A& proto) {
        str("");
        (*this) << ((ostringstream *)(&proto))->str();
        return *this;
    }

};


int main() {
    A a;
    cout << "Hello!" << endl;
    throw a;
}
[dims@testbed cpptests]$ g++ test03.cpp
[dims@testbed cpptests]$ ./a.out
Hello!
terminate called after throwing an instance of 'A'
Aborted
[dims@testbed cpptests]$


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


Эксперт
****


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

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



http://cplusplus.com/reference/iostream/ostringstream/
поищите там конструктор копирования smile 

Цитата(Dims @  5.3.2010,  20:32 Найти цитируемый пост)
На Линуксе мой код компилируется

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


Эксперт
***


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

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



Более полная проверка на Линуксе:

Код

[dims@testbed cpptests]$ cat test03.cpp
#include <sstream>
#include <iostream>

using namespace std;

class A : public ostringstream {

public:
    int myMember;

    A() : ostringstream() {
    }

    A(const A& proto) : ostringstream() {
        (*this) << ((ostringstream *)(&proto))->str();
    }

    A& operator=(const A& proto) {
        str("");
        (*this) << ((ostringstream *)(&proto))->str();
        return *this;
    }

};


int main() {

    A a1;

    a1 << "text to a1";
    cout << "a1 = " << a1.str() << endl;

    A a2;

    a2 << "text to a2";
    cout << "a2 = " << a2.str() << endl;

    cout << "copying a2 to a1" << endl;
    a1 = a2;

    a1 << "addition to a1";
    a2 << "addition to a2";

    cout << "a1 = " << a1.str() << endl;
    cout << "a2 = " << a2.str() << endl;

    cout << "complex copying a2 to a1" << endl;
    a1 = A(a2);

    cout << "a1 = " << a1.str() << endl;
    cout << "a2 = " << a2.str() << endl;

    try {
        cout << "throwing a1" << endl;
        throw a1;
    }
    catch(A &b) {
        cout << "catched = " << b.str() << endl;
    }

    cout << "bye." << endl;
}

[dims@testbed cpptests]$ ./a.out
a1 = text to a1
a2 = text to a2
copying a2 to a1
a1 = text to a2addition to a1
a2 = text to a2addition to a2
complex copying a2 to a1
a1 = text to a2addition to a2
a2 = text to a2addition to a2
throwing a1
catched = text to a2addition to a2
bye.
[dims@testbed cpptests]$


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


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


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

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



Цитата(Dims @  5.3.2010,  19:04 Найти цитируемый пост)
Ниже сообщение. Возникает ДВЕ ошибки:

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

Цитата(Dims @  5.3.2010,  19:04 Найти цитируемый пост)
О, чё на сайте говорит: http://codepad.org/8pIjcxuu 

это  логичное следствие, о котором как раз и предполагалось.

Цитата(Lazin @  5.3.2010,  19:11 Найти цитируемый пост)
ostringstream не предназначен для наследования

точнее не предназначен для того чтоб быть исключением.
smile
и компилируется ли на линуксе или нет значения не играет 
smile



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


Эксперт
***


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

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



Цитата(Lazin @  5.3.2010,  20:38 Найти цитируемый пост)
поищите там конструктор копирования smile 

Зато конструктор копирования есть в моём классе. Вы не заметили? smile

Цитата(Lazin @  5.3.2010,  20:38 Найти цитируемый пост)
там другая реализация STL

Там есть конструктор копирования в ostringstream?

Цитата(Lazin @  5.3.2010,  20:38 Найти цитируемый пост)
зачем вам использовать ostringstream вместо исключения?

Почему бы и нет? Я уже объяснял, я хочу таким способом составлять сообщения об ошибке. Это удобнее, чем складывать string-и, так как для operator<< больше определений.

Добавлено через 4 минуты и 17 секунд
Цитата(mes @  5.3.2010,  20:46 Найти цитируемый пост)
ну раз код вызывает такие ошибки, то вопрос к компилятору ..

Тогда об чём мы толкуем уже битый день? Есть на форуме компилятор, пусть ответит на мой вопрос? smile

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

Объясните. Что означает это сообщение с codepad, как его понимать?

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


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


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

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



Цитата(Dims @  5.3.2010,  19:51 Найти цитируемый пост)
Тогда об чём мы толкуем уже битый день? Есть на форуме компилятор, пусть ответит на мой вопрос? smile

мы толкуем о том, что так делать не "красиво" , а Вы о том что Вам надо, к сожалению не заметив предложенный Вам вариант удовлетворяющий как Вашим , так и компиляторным требованиям  smile
Цитата(Dims @  5.3.2010,  19:51 Найти цитируемый пост)
Есть на форуме компилятор, пусть ответит на мой вопрос? smile

Т.е. Вы хотите писать компиляторо-зависимый код  ? a может лучше написать по правилам

Цитата(Dims @  5.3.2010,  19:51 Найти цитируемый пост)
Зато конструктор копирования есть в моём классе. Вы не заметили? smile

и не только мы, а также и компилятор smile и показывает Вам, что Вы поступаете не совсем правильно.

Цитата(Dims @  5.3.2010,  19:51 Найти цитируемый пост)
Объясните. Что означает это сообщение с codepad, как его понимать?

оно говорит о том, что хотя у Вашего наследника и открытый конструктор копий, но действие не совсем законно, так как предок желал быть не копированным так как его конструктор копий закрыт. Т.е. другими словами компилятор ловит Вас на "жульничестве" smile

Eще раз повторюсь, что если посмотрите выше найдете пример, позволяющий сделать законно и без напряга то что Вы хотите.
smile


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


Эксперт
***


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

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



Цитата(mes @  5.3.2010,  22:02 Найти цитируемый пост)
a может лучше написать по правилам

По каким? Понимаете, дуть на воду я и сам умею. Назовите правило, которое я нарушил в своём примере.

Цитата(mes @  5.3.2010,  22:02 Найти цитируемый пост)
и не только мы, а также и компилятор smile и показывает Вам, что Вы поступаете не совсем правильно.

В чём же ошибка? Конструктор копирования у меня есть, присваивание у меня есть. Имею право throw-ить. 

Цитата(mes @  5.3.2010,  22:02 Найти цитируемый пост)
оно говорит о том, что хотя у Вашего наследника и открытый конструктор копий, но действие не совсем законно, так как предок желал быть не копированным так как его конструктор копий закрыт. Т.е. другими словами компилятор ловит Вас на "жульничестве" 

Не могу согласиться. Язык не требует у меня, чтобы я в копирующем конструкторе наследника вызывал именно копирующий конструктор предка (а не какой-либо другой). Следовательно, если логика моей задачи позволяет в копирующем конструкторе инициализировать базовый класс по-другому, я могу это сделать и никакого жульничества тут нет.
PM MAIL   Вверх
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   Вверх
Dims
Дата 6.3.2010, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(mes @  6.3.2010,  12:54 Найти цитируемый пост)
Никакого вызова копи-конструктора макросом не происходит, только проверяется его доступность.  


Хорошо, Вы правы, проверяется доступность. Но конструктор явно упоминается в выражении. Пример полностью аналогичен нижеследующему:

Код

struct A {
 private:
     int field;
};
struct B : A {
    void method()
    { 
        sizeof(field); // палец указывает сюда
    }
};
int main (){ 
}


То есть, вы просто пытаетесь получить свойство члена, вам недоступного. Тут ни причём копирующие конструкторы и throw. Такой код всегда будет вызывать ошибку. И место, в котором это происходит, можно указать пальцем (см. комментарий).

Можете проделать то же самое с моим примером с ostringstream?
PM MAIL   Вверх
mes
Дата 6.3.2010, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Dims @  6.3.2010,  13:38 Найти цитируемый пост)
Пример полностью аналогичен нижеследующему:

с той лишь разностью, что в Вашем случае проверка осуществляется программистом, а в моем компилятором, и мой код лишь грубая иллюстрация проверки.
smile

Цитата(Dims @  6.3.2010,  13:38 Найти цитируемый пост)
Можете проделать то же самое с моим примером с ostringstream? 

сейчас я на секундочку заскочил, вернусь - попробую разобраться, что Вы просите проделать ..
 если что, может перефразируете, что именно не понятно, так как мне кажется что нить Вашей логики я упустил..
smile


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


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


Эксперт
***


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

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



Я нашёл, в чём глюк. Ниже код.

Классы D и E оба наследуют от A (причём, D делает это косвенно и имея A виртуальным предком). В A конструктор копирования приватный (для всех), но это не мешает копировать и присваивать как D, так и E, так как в них определены свои конструкторы. Однако, стоит применить throw, возникает ошибка, причём только для класса D.

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

Код

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

struct B : virtual public A {
    B()  : A() {}
};

struct C : virtual public A {
    C()  : A() {}
};

struct D : public C, public B {
    D() : C(), B() {}
    D(const D&) : C(), B() {}
    D& operator=(const D& ano) {}
};

struct E : public A {
    E() : A() {}
    E(const E&) : A() {}
    E& operator=(const E& ano) {}
};

int main (){ 

    D d1;
    D d2(d1);
    // throw d1; // error if uncomment this

    E e1;
    E e2(e1);
    throw e1;
}


Добавлено через 7 минут и 43 секунды
P.S. Конечно, я забыл return *this; в операторе присваивания...

Проверка компилятором codepad подтверждает гипотезу, что я напал на след: http://codepad.org/Otzbacg6

Компилятор тут показывает ошибку точнее, чем VS, но и здесь ошибочным является только код D, но не E.

Осталось ещё разобраться, как удовлетворить "should be explicitly initialized in the copy constructor", ну и понять, откуда это требование возникает...

Добавлено через 9 минут и 7 секунд
Цитата(mes @  6.3.2010,  16:12 Найти цитируемый пост)
с той лишь разностью, что в Вашем случае проверка осуществляется программистом, а в моем компилятором

Не понял. Обоснуйте это утверждение.

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


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


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

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



...

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


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


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


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

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



перечитал еще раз топик, вроде разобрался где свернули в разные стороны. smile
сейчас объясню.

Добавлено @ 19:15
Цитата(Dims @  5.3.2010,  19:04 Найти цитируемый пост)
О, чё на сайте говорит: http://codepad.org/8pIjcxuu 

вот тут Вас интересует почему возникает ошибка компиляции, а не почему так нельзя делать.

Цитата

Осталось ещё разобраться, как удовлетворить "should be explicitly initialized in the copy constructor"

Цитата

12.6.2/5 Initialization shall proceed in the following order:
— First, and only for the constructor of the most derived class as described below, virtual base classes shall
be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph
of base classes, where “left-to-right” is the order of appearance of the base class names in the derived
class base-specifier-list.
— Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list
(regardless of the order of the mem-initializers).
— Then, nonstatic data members shall be initialized in the order they were declared in the class definition
(again regardless of the order of the mem-initializers).
— Finally, the body of the constructor is executed.

вот теперь компилируется : http://codepad.org/dSptN7Fb, 
 но за работоспособность не ручаюсь - не настолько хорошо знаю язык ,
в душе и  по обоснованиям изложенных выше полагаю что ill formed 
 smile

ответ устраивает или я опять не на то ответил ? smile

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


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

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

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

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

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


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

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


 




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


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

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