Re[4]: Сокрытие не-public членов классов
От: Павел Кузнецов  
Дата: 23.01.03 13:56
Оценка: 31 (3)
Здравствуйте, MaximE, Вы писали:

ПК>>часто делают допущение, что неопределенность поведения, упомянутая в п. 17.4.3.6/2, применительно к std::auto_ptr<>, относится к <...>


ME>в своей статье Саттер говорит, что чтобы избежать пресловутого undefined behaviour необходимо определить конструктор, копирующий конструктор, оператор присваивания и деструктор.


Что свидетельствует о наличии некоторых — возможно, вполне обоснованных с практической точки зрения — предположений о реализации std::auto_ptr<>. Для того, чтобы оценить границы применимости подобных рассуждений, просто скопируй куда-нибудь реализацию std::auto_ptr<>, поставляемую с твоим компилятором, и добавь в начало определения нового (назовем его my_auto_ptr<>) шаблона строку:

enum { __element_size = sizeof(_Ty) };


заменив _Ty на имя параметра шаблона, если оно отличается. Полученный вариант, будучи поставляем разработчиком компилятора, в той же мере соответствует стандарту, что и первоначальная версия. Теперь попробуй инстанциировать полученный шаблон my_auto_ptr<> неполным типом. Неизбежная ошибка компиляции — проявление неопределенного поведения, которое не выйдет обойти никакими конструкторами или деструкторами.

ME>В форумах, подобных comp.lang.c++.moderated, Саттер неоднократно отвечал на подобные вопросы.


В этих "ответах" Саттер, подразумевая истинность своих предположений о реализации std::auto_ptr<>, делает какие-то выводы, упоминая главу 12 стандарта и т.п. Ни одного прямого ответа на упоминание п. 17.4.3.6/2, насколько мне известно, он не давал.

ME>Думаю, что он достатчно авторитетен и осведомлен (Secretary, ISO WG21/ANSI J16 (C++) standards committee)


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

ME>обо всех тонкостях и подводных камнях использования pimpl и auto_ptr.


Однако специально для любителей авторитетов я привел ссылку на статью Мэта Остерна, куда уж как более авторитетного в данных вопросах, нежели Саттер. Статья включает, помимо соответствующих формулировок, и обоснование решений, принятых комитетом в этом отношении.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Сокрытие не-public членов классов
От: Павел Кузнецов  
Дата: 23.01.03 11:27
Оценка: 15 (3)
Здравствуйте, MaximE, Вы писали:

ME>
ME>class DataMapper : public Reference
ME>{
ME>public:
ME>    DataMapper();
ME>    ~DataMapper();
ME>    // ...
ME>private:
ME>    std::auto_ptr<struct DataMapperImpl> _pimpl; // непрозрачный указатель на реализацию
ME>};
ME>


Строго говоря, если класс DataMapperImpl не является полностью определенным в месте определения члена _pimpl, выполнение или компиляция программы, содержащей подобный фрагмент, согласно п. 17.4.3.6/2 текущего стандарта, приводит к undefined behavior:

17.4.3.6 Other functions
2
In particular, the effects are undefined in the following cases:
— if an incomplete type (3.9) is used as a template argument when instantiating a template component.


Т.к. определение нестатической переменной-члена требует полностью определенного типа (9.2/8), точкой инстанциирования шаблона std::auto_ptr<> в данном случае является определение члена _pimpl в определении класса DataMapper (14.7.1).

Примером проявления упомянутого неопределенного поведения может служить ошибка компиляции, если определение шаблона std::auto_ptr<> содержит sizeof(T). Конечно, кто-нибудь может — весьма справедливо — поинтересоваться: зачем это в определении std::auto_ptr<> может понадобиться sizeof(T)? Естественно, для std::auto_ptr<> разумного ответа, скорее всего, не последует. Тем не менее, все это соображения о деталях реализации стандартной библиотеки, что, очевидно, является не более чем спекуляцией. Единственным — законным — руководством оценки правильности использования стандартной библиотеки является стандарт. В том виде, как он написан сейчас, стандарт однозначно трактует подобную программу как приводящую к неопределенному поведению. При написании стандарта, члены рабочей группы решили воздержаться от классификации шаблонов стандартной библиотеки на те, которые можно инстанциировать неполными типами, и те, которые нельзя, ограничившись общей "запретительной" формулировкой (более подробно см., например, статью Containers of Incomplete Types, автором которой является Matt Austern, председатель "библиотечной" рабочей группы комитета стандартизации).

С практической точки зрения часто делают допущение, что неопределенность поведения, упомянутая в п. 17.4.3.6/2, применительно к std::auto_ptr<>, относится к неопределенности поведения при инстанциировании деструктора std::auto_ptr<>, который в том или ином виде должен содержать выражение вида: delete p. Подобные размышления можно встретить и в небезызвестной статье Герба Саттера. Однако следует помнить, что в основании всех подобных рассуждений лежат предположения о реализации стандартной библиотеки, ни в коей мере не подкрепленные стандартом.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 22.01.03 08:01
Оценка: 2 (1)
Здравствуйте, Сray, Вы писали:

С>Я, конечно, понимаю, что можно все необходимые include засунуть в "someclass.h". Собственно, так обычно и делаю. Но может есть какие-нибуть другие варианты покрасивей?

С>Если SomeClass есть часть какой-то библиотеки, то получается, что чтобы использовать ее нужно перечислить кучу заголовочных файлов предназначенных "для внутреннего использования" внутри класса.
С>Sorry если вопрос глупый

Используй идиому Pimpl.


///////////////////////////////////////////////////////////////////////////////
// DataMapper.h

#pragma once

#include "Reference.h"

class DataMapper : public Reference
{
public:
    DataMapper();
    ~DataMapper();
    // ...
private:
    std::auto_ptr<struct DataMapperImpl> _pimpl; // непрозрачный указатель на реализацию
};



///////////////////////////////////////////////////////////////////////////////
// DataMapper.cpp

#include "stdafx.h"
#include "DataMapper.h"

using namespace ADODB;
using namespace std;

///////////////////////////////////////////////////////////////////////////////

struct DataMapperImpl
{
    DataMapperImpl() : _connection(__uuidof(Connection))
    {
        _connection->Open(sqlConnection, _bstr_t(), _bstr_t(), adConnectUnspecified);
    };

    _ConnectionPtr _connection;
};

///////////////////////////////////////////////////////////////////////////////

DataMapper::DataMapper()
    :    _pimpl(new DataMapperImpl)
{
}

///////////////////////////////////////////////////////////////////////////////


Подробнее: Compilation Firewalls
Сокрытие не-public членов классов
От: Сray  
Дата: 22.01.03 02:03
Оценка:
Предположим, что в неком заголовочном файле "someclass.h" содержится такая запись:
class SomeClass
{
public:
    SomeClass();
    virtual ~SomeClass();
    int DoSomething(int);
private:
    vector<int> m_V;
    map<int,int> m_M;
    // etc...
};

В файле "someclass.cpp" тогда должно быть
#include <vector>
#include <map>
#include <evrething> // :-)
#include "someclass.h"


Чтобы использовать этот класс я должен перечислить те-же include. Хотя ни один из открытых членов не использует в параметрах и в возврате ни vector ни map или что-там там еще требующее дополнительных заголовочных файлов.
Хотелось бы использовать только #include "someclass.h" во всех местах где данный класс вызывается.
Я, конечно, понимаю, что можно все необходимые include засунуть в "someclass.h". Собственно, так обычно и делаю. Но может есть какие-нибуть другие варианты покрасивей?
Если SomeClass есть часть какой-то библиотеки, то получается, что чтобы использовать ее нужно перечислить кучу заголовочных файлов предназначенных "для внутреннего использования" внутри класса.
Sorry если вопрос глупый
Re: Сокрытие не-public членов классов
От: Alexey Shirshov Россия http://wise-orm.com
Дата: 22.01.03 03:01
Оценка:
Здравствуйте, Сray, Вы писали:

[]
С>Я, конечно, понимаю, что можно все необходимые include засунуть в "someclass.h". Собственно, так обычно и делаю. Но может есть какие-нибуть другие варианты покрасивей?

Включи их в stdafx.h. Не знаю на счет красивости, но скорость компиляции точно увеличит. А если нужно защититься, то в someclass.h можно написать:

#ifndef _VECTOR_
#error I need <vector> to be included in stdafx.h
#endif


[]
Re: Сокрытие не-public членов классов
От: Аноним  
Дата: 22.01.03 07:03
Оценка:
Так вроде это известная особенность С++ — просачивание реализации в интерфейс через private-часть объявления класса. Чтобы этого избежать, используются либо интерфейсы (абстрактные классы) + фабрики, либо классы-обертки, единственный private-член которых — указатель на класс-реализацию. Во втором случае делается неполное обявление класса-реализации. У Мейерса все это подробно описано. Здесь где-то рядом был вопрос о том, как попроще кодировать делегирование.
Re[2]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 22.01.03 14:14
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>std::auto_ptr<struct DataMapperImpl> _pimpl; // непрозрачный указатель на реализацию


По стандарту, это может привести ... к форматированию жесткого диска Подробней здесь
Автор: Павел Кузнецов
Дата: 08.01.03
Re[3]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 22.01.03 16:18
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, MaximE, Вы писали:


ssm>
ME>>std::auto_ptr<struct DataMapperImpl> _pimpl; // непрозрачный указатель на реализацию
ssm>


ssm> По стандарту, это может привести ... к форматированию жесткого диска Подробней здесь
Автор: Павел Кузнецов
Дата: 08.01.03


Undefined behavior могло бы возникнуть, если бы я не определил деструктор у DataMapper. В этом случае компилятор сгенерировал бы деструктор по-умолчанию в каждом объектнике, пользующем DataMapper, что и было бы причиной undefined behavior.
Re: Сокрытие не-public членов классов
От: grs Россия  
Дата: 22.01.03 16:29
Оценка:
Здравствуйте, Сray, Вы писали:

С>Предположим, что в неком заголовочном файле "someclass.h" содержится такая запись:

С>
С>class SomeClass
С>{
С>public:
С>    SomeClass();
С>    virtual ~SomeClass();
С>    int DoSomething(int);
С>private:
С>    vector<int> m_V;
С>    map<int,int> m_M;
С>    // etc...
С>};
С>

С>В файле "someclass.cpp" тогда должно быть
С>
С>#include <vector>
С>#include <map>
С>#include <evrething> // :-)
С>#include "someclass.h"
С>


С>Чтобы использовать этот класс я должен перечислить те-же include. Хотя ни один из открытых членов не использует в параметрах и в возврате ни vector ни map или что-там там еще требующее дополнительных заголовочных файлов.

С>Хотелось бы использовать только #include "someclass.h" во всех местах где данный класс вызывается.
С>Я, конечно, понимаю, что можно все необходимые include засунуть в "someclass.h". Собственно, так обычно и делаю. Но может есть какие-нибуть другие варианты покрасивей?
С>Если SomeClass есть часть какой-то библиотеки, то получается, что чтобы использовать ее нужно перечислить кучу заголовочных файлов предназначенных "для внутреннего использования" внутри класса.
С>Sorry если вопрос глупый

Вообще-то я всегда думал, что ежели в объявлении SomeClass используются vector, map и т.д, то в этом же заголовке ты и обязан писать #include <vector>, #include <map> и т.д. Других вариатов я просто не вижу, особенно, если дело касается библиотек. Твои коллеги, которые будут использовать SomeClass, даже задумываться не должны, что кроме #include "someclass.h", они должны вызывать еще какой-то заголовок. А за "варианты покрасивие" нормальные руководители проекта отрывают руки. И правильно делают...
Re[4]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 22.01.03 16:34
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Undefined behavior могло бы возникнуть, если бы я не определил деструктор у DataMapper. В этом случае компилятор сгенерировал бы деструктор по-умолчанию в каждом объектнике, пользующем DataMapper, что и было бы причиной undefined behavior.


открываем стандарт и смотрим пункт 17.4.3.6, а именно последнюю часть:

In particular, the effects are undefined in the following cases:

-if an incomplete type(3.9) is used as template argument when instanting a template component


что и имеет место в приведенном тобой коде
Re[2]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 22.01.03 16:45
Оценка:
Здравствуйте, grs, Вы писали:

grs>А за "варианты покрасивие" нормальные руководители проекта отрывают руки.


Вопервых "нормальные руководители" вообще не должны лазить по исходникам : это — не их парафия, их задача — правильно сделать постановку задачи и, может быть в некоторых случаях, предоставить программисту открытый интерфейс реализуемого им класса.

grs> И правильно делают...


а во вторых, если уж "нормальные руководители" начали лазить по коду, то незнание патерна(или как это правильно называеться) pimpl вообще ставит под сомнение их уровень квалификации
Re[5]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 22.01.03 16:55
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, MaximE, Вы писали:


ME>>Undefined behavior могло бы возникнуть, если бы я не определил деструктор у DataMapper. В этом случае компилятор сгенерировал бы деструктор по-умолчанию в каждом объектнике, пользующем DataMapper, что и было бы причиной undefined behavior.


ssm>открываем стандарт и смотрим пункт 17.4.3.6, а именно последнюю часть:


ssm>In particular, the effects are undefined in the following cases:


ssm>-if an incomplete type(3.9) is used as template argument when instanting a template component


ssm>что и имеет место в приведенном тобой коде


Это так. Но пользователем этой структуры является только DataMapper. В *.cpp DataMapperImpl полностью определен и вызов ~auto_ptr<DataMapperImpl> происходит только из определенного деструктора DataMapper, что не приводит к неопределенному поведению.
Это тоже самое, как если бы я написал так:

class DataMapper : public Reference
{
public:
    DataMapper();
    ~DataMapper();
private:
    //const std::auto_ptr<struct DataMapperImpl> _pimpl;
    struct DataMapperImpl* _pimpl;
};



///////////////////////////////////////////////////////////////////////////////

struct DataMapperImpl
{
    DataMapperImpl() : _connection(__uuidof(Connection))
    {
        _connection->Open(sqlConnection, _bstr_t(), _bstr_t(), adConnectUnspecified);
    };

    _ConnectionPtr _connection;
};

///////////////////////////////////////////////////////////////////////////////

DataMapper::DataMapper()
    :    _pimpl(new DataMapperImpl)
{
}

///////////////////////////////////////////////////////////////////////////////

DataMapper::~DataMapper()
{
    delete _pimpl;
}


Рекоммендую, все-таки, почитать Саттера по вышеприведенной ссылке
Re[6]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 22.01.03 17:06
Оценка:
Здравствуйте, MaximE, Вы писали:


ME>Это так. Но пользователем этой структуры является только DataMapper. В *.cpp DataMapperImpl полностью определен и вызов ~auto_ptr<DataMapperImpl> происходит только из определенного деструктора DataMapper, что не приводит к неопределенному поведению.


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

ME>Это тоже самое, как если бы я написал так:

ME> //const std::auto_ptr<struct DataMapperImpl> _pimpl;
ME> struct DataMapperImpl* _pimpl;

вот если бы ты поступил так, то сделал бы в точности как писал Саттер

ME>Рекоммендую, все-таки, почитать Саттера по вышеприведенной ссылке


да он у меня на столе в бумажном виде лежит
Re[7]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 22.01.03 18:59
Оценка:
Здравствуйте, ssm, Вы писали:

ME>>Рекоммендую, все-таки, почитать Саттера по вышеприведенной ссылке


ssm>да он у меня на столе в бумажном виде лежит


Тогда ты, должно быть, туда не заглядывал.
Возьми же наконец его со стола и открой на стр.267 "Упаковка членов-указателей" и затем на стр.271 "Оболочка указателей-членов" (так перевела некто Красикова). Там как раз обсуждается использование Pimpl и auto_ptr.
Re: Сокрытие не-public членов классов
От: Алексей Владимирович Миронов Россия  
Дата: 23.01.03 01:17
Оценка:
Здравствуйте, Сray, Вы писали:

С>Я, конечно, понимаю, что можно все необходимые include засунуть в "someclass.h". Собственно, так обычно и делаю. Но может есть какие-нибуть другие варианты покрасивей?


Не знаю, насколько красив мой вариант, но когда-то (на "чистом" C) я поступал следующим образом:

#ifndef RETAIL

#include "header1.h"
#include <header2.h>

struct MARC_RECORD
{
  int field1;
  char *field2;
};

#else

struct MARC_RECORD
{
  int unused;
}

#endif

typedef struct MARC_RECORD *HMARC;

int marc_get_field1 (HMARC mrc);


Перед выдачей marc.h "на гора" он пропускается через программу ifdef:

ifdef -DRETAIL ./marc.h -o ../retail/marc.h


Думается, метод применим и в случае C++:

class SomeClass
{
public:
    SomeClass();
    virtual ~SomeClass();
    int DoSomething(int);
#ifndef RETAIL
private:
    vector<int> m_V;
    map<int,int> m_M;
    // etc...
#endif
};


Основной недостаток данного метода для меня -- [пользователю] невозможно создать объект на стеке или в статической переменной. Точнее говоря, чтобы это стало возможным, нужно "добивать" фиктивную структуру до правильного размера.
Re[8]: Сокрытие не-public членов классов
От: romasha Украина  
Дата: 23.01.03 06:36
Оценка:
ME>Возьми же наконец его со стола и открой на стр.267 "Упаковка членов-указателей" и затем на стр.271 "Оболочка указателей-членов" (так перевела некто Красикова). Там как раз обсуждается использование Pimpl и auto_ptr.

О какой книге идет речь ? Интересно почитать. (или ссылку).
Re[9]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 23.01.03 07:41
Оценка:
Здравствуйте, romasha, Вы писали:

R>О какой книге идет речь ? Интересно почитать. (или ссылку).


Herb Sutter "Exceptional C++". Практически все содержание книги лежит у него на сайте в разделе Guru of the Week
Re[8]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 23.01.03 07:45
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Тогда ты, должно быть, туда не заглядывал.

ME>Возьми же наконец его со стола и открой на стр.267 "Упаковка членов-указателей" и затем на стр.271 "Оболочка указателей-членов" (так перевела некто Красикова). Там как раз обсуждается использование Pimpl и auto_ptr.

а еще и на 165 стр.

Ну тогда получаеться, что либо Герб незнает о таком пункте стандарта (что скорее всего врядли), либо знает и умышленно скрывает .
Ведь ясно в стандарте написано, что нельзя так делать. Как же быть
Что интерестно скажет Павел Кузнецов по этому поводу? Похожая тема поднималась уже здесь
Автор: ssm
Дата: 08.01.03
, но ПК в своем ответе дал точно понять что так делать нельзя, если следовать стандарту, а тут Герб...
Так кому же верить?
Re[9]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 23.01.03 08:06
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Ну тогда получаеться, что либо Герб незнает о таком пункте стандарта (что скорее всего врядли), либо знает и умышленно скрывает .

ssm>Ведь ясно в стандарте написано, что нельзя так делать. Как же быть

Есть еще вариант, что ты прочитал фразу:

-if an incomplete type(3.9) is used as template argument when instanting a template component


но не удосужился узнать, что же такое "instanting a template".

Смотри 14.7 Template instantiation and specialization
Re[8]: Сокрытие не-public членов классов
От: alexkro  
Дата: 23.01.03 09:24
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, ssm, Вы писали:


ME>>>Рекоммендую, все-таки, почитать Саттера по вышеприведенной ссылке


ssm>>да он у меня на столе в бумажном виде лежит


ME>Тогда ты, должно быть, туда не заглядывал.

ME>Возьми же наконец его со стола и открой на стр.267 "Упаковка членов-указателей" и затем на стр.271 "Оболочка указателей-членов" (так перевела некто Красикова). Там как раз обсуждается использование Pimpl и auto_ptr.

Я думаю, лучше почитать здесь: http://www.gotw.ca/gotw/062.htm
Re[10]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 23.01.03 09:49
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Есть еще вариант, что ты прочитал фразу:

ME>

ME>-if an incomplete type(3.9) is used as template argument when instanting a template component


Если ты читал это, то почему спрашиваешь?

ME>но не удосужился узнать, что же такое "instanting a template".


ME>Смотри 14.7 Template instantiation and specialization


Если ты удосужился узнать, что же такое "instanting a template", то может просвятишь меня когда будет инстанцироваться std::auto_ptr<DataMapperImpl> в твоем случае? Насколько я понимаю это происходит в клиентском коде:

#include "DataMapper.h"

int main(){

  DataMapper dm;  //я думаю что здесь, хочешь сказать, что в этой точке DataMapperImpl not incomplete type ?
...
}
Re[11]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 23.01.03 09:57
Оценка:
Здравствуйте, ssm, Вы писали:


ssm>#include "DataMapper.h"

ssm>int main(){

ssm>  DataMapper dm;  //я думаю что здесь, хочешь сказать, что в этой точке DataMapperImpl not incomplete type ?
ssm>...
ssm>}


Кажется я допер сам
инстанцирование происходит в конструкторе DataMapper, а именно:

DataMapper::DataMapper()
    :    _pimpl(new DataMapperImpl)
{
}


а здесь то DataMapperImpl уже точно определен.
Если я неправ, то поправь
Re[3]: Сокрытие не-public членов классов
От: grs Россия  
Дата: 23.01.03 11:42
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, grs, Вы писали:


grs>>А за "варианты покрасивие" нормальные руководители проекта отрывают руки.


ssm>Вопервых "нормальные руководители" вообще не должны лазить по исходникам : это — не их парафия, их задача — правильно сделать постановку задачи и, может быть в некоторых случаях, предоставить программисту открытый интерфейс реализуемого им класса.


grs>> И правильно делают...


ssm>а во вторых, если уж "нормальные руководители" начали лазить по коду, то незнание патерна(или как это правильно называеться) pimpl вообще ставит под сомнение их уровень квалификации


Ну не надо доводить мои слова до абсурда. Шаблоны (или паттерны) тут вообще не причем, тут речь идет об элементарных правилах программирования на С++. Особенно, если работаешь в команде.
А по поводу руководителя, а он по исходникам и не лазает. Объясняю алгоритм. Получаешь ты такой шедевр типа someclass.h. Подходишь к автору и говоришь, что у меня мол нечего не компилится не фига. В ответ на предложение включить такие-то и такие-то заголовки, вежливо объясняешь ему, что это его проблема. Если не понимает — идешь к руководителю, а он приступает к ампутации конечностей. Все просто!
Re[4]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 23.01.03 11:59
Оценка:
Здравствуйте, grs, Вы писали:

grs>Ну не надо доводить мои слова до абсурда. Шаблоны (или паттерны) тут вообще не причем, тут речь идет об элементарных правилах программирования на С++. Особенно, если работаешь в команде.

grs>А по поводу руководителя, а он по исходникам и не лазает. Объясняю алгоритм. Получаешь ты такой шедевр типа someclass.h. Подходишь к автору и говоришь, что у меня мол нечего не компилится не фига.

Мы же ведь говорили о "вариантах покрасивие", а не о приведенном автором коде
Re[3]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 23.01.03 13:07
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>С практической точки зрения часто делают допущение, что неопределенность поведения, упомянутая в п. 17.4.3.6/2, применительно к std::auto_ptr<>, относится к неопределенности поведения при инстанциировании деструктора std::auto_ptr<>, который в том или ином виде должен содержать выражение вида: delete p. Подобные размышления можно встретить и в небезызвестной статье Герба Саттера. Однако следует помнить, что в основании всех подобных рассуждений лежат предположения о реализации стандартной библиотеки, ни в коей мере не подкрепленные стандартом.


Я, безусловно, снимаю свою несуществующую шляпу перед Павлом.

Но в своей статье Саттер говорит, что чтобы избежать пресловутого undefined behaviour необходимо определить конструктор, копирующий конструктор, оператор присваивания и деструктор.
В форумах, подобных comp.lang.c++.moderated, Саттер неоднократно отвечал на подобные вопросы.
Думаю, что он достатчно авторитетен и осведомлен (Secretary, ISO WG21/ANSI J16 (C++) standards committee) обо всех тонкостях и подводных камнях использования pimpl и auto_ptr.
Re[5]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 23.01.03 14:30
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Согласен со всем, но одно маленькое "но":

ПК>заменив _Ty на имя параметра шаблона, если оно отличается. Полученный вариант, будучи поставляем разработчиком компилятора, в той же мере соответствует стандарту, что и первоначальная версия. Теперь попробуй инстанциировать полученный шаблон my_auto_ptr<> неполным типом. Неизбежная ошибка компиляции — проявление неопределенного поведения, которое не выйдет обойти никакими конструкторами или деструкторами.


Т.е. неопределенного поведения не возникает, так как невозможно скомпилировать. Это говорит только о том, что инстанцирование происходит в объявлении класса.

Признаю свою полную некомпетентность
Re[6]: Сокрытие не-public членов классов
От: Павел Кузнецов  
Дата: 23.01.03 14:39
Оценка:
Здравствуйте, MaximE, Вы писали:

ПК>>Неизбежная ошибка компиляции — проявление неопределенного поведения


ME>неопределенного поведения не возникает, так как невозможно скомпилировать


Невозможность скомпилировать — один из многих вариантов проявления неопределенного поведения :-)

1.3.12 undefined behavior
behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements. <...> [Note: permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Сокрытие не-public членов классов
От: grs Россия  
Дата: 23.01.03 16:27
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, grs, Вы писали:


ssm>Мы же ведь говорили о "вариантах покрасивие", а не о приведенном автором коде


Ага, читал. Только все эти варианты, паттерн _pimpl и т.д. — это частный случай, кстати, между нами, не так уж часто применяеемый. А ты представь, что этот преслоутый SomeClass, ну скажем диалоговое окошко, которое ты должен вызвать из своего диалогового окошка. И чего, каждый раз, будешь паттерн лепить из-за private vector<int>? Даже не смешно!
Просто я отчечал на первое сообщение в ветке, и кстати, даже не на него, а на безумное, на мой взгляд, предложение Alexey Shirshov'а о включении заголовков, которые ДОЛЖНЫ быть в someclass.h в stdafx.h, за что, повторюсь, я считаю нужно просто руки отрывать. Чтобы другим неповадно было. Просто в одном проекте, где я участвую где-то 700 исходников, а в другом — 300, я как представил картинку полной переборки при подходе Cray'я и Alexey Shirshov'а... А вы говорите паттерны, паттерны. Прежде чем заниматься высшей математикой, неплохо бы выучить таблицу умножения!
Re[6]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 23.01.03 17:01
Оценка:
Здравствуйте, grs, Вы писали:

grs>Ага, читал. Только все эти варианты, паттерн _pimpl и т.д. — это частный случай, кстати, между нами, не так уж часто применяеемый. А ты представь, что этот преслоутый SomeClass, ну скажем диалоговое окошко, которое ты должен вызвать из своего диалогового окошка. И чего, каждый раз, будешь паттерн лепить из-за private vector<int>? Даже не смешно!


При чем тут vector<int>?

grs>Просто я отчечал на первое сообщение в ветке, и кстати, даже не на него, а на безумное, на мой взгляд, предложение Alexey Shirshov'а о включении заголовков, которые ДОЛЖНЫ быть в someclass.h в stdafx.h, за что, повторюсь, я считаю нужно просто руки отрывать.


С этим полностью согласен

grs>Чтобы другим неповадно было. Просто в одном проекте, где я участвую где-то 700 исходников, а в другом — 300, я как представил картинку полной переборки при подходе Cray'я и Alexey Shirshov'а...


Ты лучше себе преставь другую картинку: возьмем для примера windows.h, содержащем "милион" всяких определений и прочего кода. Допустим 300 файлов твоего проэкта инклудят windows.h. Что повлечет за собой изменение одного определения в windows.h ? Правильный ответ,- перекомпиляцию всех модулей его использующих. В случае же с инкапсулированной, посредством pimpl реализацией, перекомпилировать прийдеться только модули реализации. Тем более : инкапсуляция — сила, или ты и с этим не согласен? Вот тебе другой пример:конструирование необязательных мемберов объекта, или ты предлагаешь использовать дедовский двухпроходный метод ? Да и вообще зачем клиенту знать о внутренней реализации твоего класса? Его дело — использовать то, что ты ему предоставишь в открытом интерфейсе. Зачем тратить его время на компиляцию того, что можно скрыть? Скажешь мне пофиг, у моего компилера реализованы precompiled headers? Ну дык подумай о других

grs>А вы говорите паттерны, паттерны. Прежде чем заниматься высшей математикой, неплохо бы выучить таблицу умножения!

Ну дык никто тебе этого незапрещает, учи на здоровье
Re[6]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 02:23
Оценка:
Здравствуйте, grs, Вы писали:

> Просто в одном проекте, где я участвую где-то 700 исходников, а в другом — 300, я как представил картинку полной переборки при подходе Cray'я и Alexey Shirshov'а...


А теперь представь такую ситуацию. Есть некий проект, который условно разделен на 2 части: алгоритмическую и интерфейсную. И эти части в каких-то местах между собой взаимодействуют. Интерфейсная часть может быть написана для Windows в оконном режиме, Windows в режиме командной строки, вообще для другой операционки.
Алгоритмической части проекта (ей кроме C++ с STL ничего больше не нужно) вообще наплевать на реализацию интерфейсной части. А ты предлагаешь включить туда кучу OS-зависимых заголовочных файлов, да еще, видимо, наставить #ifdef в зависимости от варианта интерфейсной части.
Задавая вопрос, я хотел услышать варианты как обойтись без накладных расходов по вызову кучи заголовочных файлов, имеющих к алгоритмической части весьма косвнное отношение.
Про фабрики классов и pimpl-ы я знаю и этот вариант мне, в принципе, подходит. Думал, может есть еще какие варианты...
Тем не менее, дискуссия ssm-MaximE-Павел_Кузнецов была для меня довольно полезной. Узнал про "подводные камни". Спасибо.
Re[2]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 04:07
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>
ME>///////////////////////////////////////////////////////////////////////////////
ME>// DataMapper.h

ME>#pragma once

ME>#include "Reference.h"

ME>class DataMapper : public Reference
ME>{
ME>public:
ME>    DataMapper();
ME>    ~DataMapper();
ME>    // ...
ME>private:
ME>    std::auto_ptr<struct DataMapperImpl> _pimpl; // непрозрачный указатель на реализацию
ME>};
ME>


Про то, можно ли использовать std::auto_ptr или нет тут много говорилось. А я вот хотел бы спросить- а нужно ли оно здесь? Разве нельзя создавать DataMapperImpl в конструкторе и в деструкторе потом уничтожать?
Re[3]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 07:36
Оценка:
Здравствуйте, Сray, Вы писали:

С>Про то, можно ли использовать std::auto_ptr или нет тут много говорилось. А я вот хотел бы спросить- а нужно ли оно здесь? Разве нельзя создавать DataMapperImpl в конструкторе и в деструкторе потом уничтожать?


вот такой пример должен тебе все объяснить:


//DataMapper.h
class DataMapper : public Reference{
...
  struct DataMapper * _pimpl;  
  f(){}
...
};

//DataMapper.cpp
DataMapper::DataMapper() : _pimpl(new DataMapperImpl()) {
  f();
}

если f() кинет exception, то объект класса DataMapper создан не будет, следовательно деструктор, в котором будет нечто


DataMapper::~DataMapper() : _pimpl(new DataMapperImpl()) {
  delete _pimpl;
}


тоже небудет вызван, отсюда имеем утечку памяти. можно конечно завернуть "new DataMapperImpl()" в блок try-except, но зачем? ведь управляющие объекты были созданы специально для этих целей
Re[4]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 07:55
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, Сray, Вы писали:


ssm>если f() кинет exception, то объект класса DataMapper создан не будет, следовательно деструктор, в котором будет нечто


[skipped]

ssm>тоже небудет вызван, отсюда имеем утечку памяти. можно конечно завернуть "new DataMapperImpl()" в блок try-except, но зачем? ведь управляющие объекты были созданы специально для этих целей


Если конструктор кинет exception, то деструктор вызван не будет.
Re[5]: Сокрытие не-public членов классов
От: MaximE Великобритания  
Дата: 24.01.03 07:56
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Однако специально для любителей авторитетов я привел ссылку на статью Мэта Остерна, куда уж как более авторитетного в данных вопросах, нежели Саттер. Статья включает, помимо соответствующих формулировок, и обоснование решений, принятых комитетом в этом отношении.


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

Вывод: для собственных шаблонов мы всегда можем сказать, ведет ли их использование с неполными типами к undefined behaviour.

Что касается auto_ptr и pimpl, глубокое IMHO, семантика auto_ptr настолько ясна, что было бы удивительно, чтобы полный тип ему требовался кроме как для delete. Думаю, на этом же и основаны и известные нам рассуждения Саттера.
Re[5]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 08:00
Оценка:
Здравствуйте, Сray, Вы писали:

ssm>>тоже небудет вызван, отсюда имеем утечку памяти. можно конечно завернуть "new DataMapperImpl()" в блок try-except, но зачем? ведь управляющие объекты были созданы специально для этих целей


С>Если конструктор кинет exception, то деструктор вызван не будет.


если ты о деструкторе DataMapper, то я так и написал, а если ты о деструкторе auto_ptr<> то ты ошибаешься, т.к. в процессе раскрутки стека будут вызваны деструкторы уже созданных подобъектов(базовых классов, агрегированных данным)
Re[6]: Сокрытие не-public членов классов
От: Павел Кузнецов  
Дата: 24.01.03 08:04
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Однако ты дал крайне провакационную ссылку :))


:-)

ME>Мэт говорит, что они решили просто взять и запретить к чертям использование неполных типов для шаблонов в общем, и для STL в частности.


"В общем" — значит для шаблонов стандартной библиотеки. К шаблонам, определяемым пользователем это отношения не имеет.

ME>делает предположение, что в следущей версии стандарта будет указано, какие шаблоны STL допускается использовать с неполными типами.


Эта тема периодически всплывает то в clc++m, то в csc++. Естественно, текущее состояние дел воспринимается большинством заинтересованных лиц слишком ограничивающим. Например, переносимая реализация шаблона контейнера, представляющего собой граф, из-за этого драконовского правила изрядно усложняется.

ME>Вывод: для собственных шаблонов мы всегда можем сказать, ведет ли их использование с неполными типами к undefined behaviour.


Безусловно.

ME>Что касается auto_ptr и pimpl, глубокое IMHO, семантика auto_ptr настолько ясна, что было бы удивительно, чтобы полный тип ему требовался кроме как для delete.


С этим я тоже полностью согласен. Именно поэтому разделил свое первоначальное сообщение на две части: "теоретическую" и "практическую". Тем не менее, факт остается фактом: использование std::auto_ptr<> для реализации PIMPL — полностью на свой страх и риск.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 08:05
Оценка:
Не дописал, sorry...

Если конструктор кинет exception, то деструктор вызван не будет.
Единственное что нужно сделать ~DataMapper() — это delete _pimpl.
Он этого не сделает. Но это нормально- т.к. объект не был создан.

Поэтому я и не понимаю зачем здесь auto_ptr.

Вот если бы в конструкторе по new создавалось несколько объектов- тогда понятно. Но это не наш случай. У нас на один DataMapper приходится один DataMapperImpl
Re[6]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 08:16
Оценка:
Здравствуйте, Сray, Вы писали:

С>Не дописал, sorry...


С>Если конструктор кинет exception, то деструктор вызван не будет.

С>Единственное что нужно сделать ~DataMapper() — это delete _pimpl.
С>Он этого не сделает. Но это нормально- т.к. объект не был создан.

Но _pimpl то уже создан!!!

С>Поэтому я и не понимаю зачем здесь auto_ptr.


Еще раз: для устранения возможной утечки памяти при генерации исключения конструктором DataMapper при уже созданом _pimpl

С>Вот если бы в конструкторе по new создавалось несколько объектов- тогда понятно. Но это не наш случай. У нас на один DataMapper приходится один DataMapperImpl



#include <iostream>

struct A{
  char dummy[1000];
  static int count;
  A(){ count ++;}
  ~A(){ count --;}
};

int A::count = 0;

class B{
public:
  B() : a(new A()){
     throw "!!!";
  }
  ~B() {delete a;}
private:
  A * a;
};


int main(){
  try{
    B b;  
  }
  catch(...)
  {
     std::cout << "Утечка памяти >= " << A::count * sizeof(A) << std::endl;
  }
}
Re[7]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 08:20
Оценка:
Здравствуйте, ssm, Вы писали:


ssm>int main(){
       return 0;  :))   
ssm>}
Re[7]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 08:24
Оценка:
Здравствуйте, ssm, Вы писали:


а теперь замени:


ssm>class B{
ssm>public:
ssm>  B() : a(new A()){
ssm>     throw "!!!";
ssm>  }
ssm>  ~B() {delete a;}
ssm>private:
ssm>  A * a;
ssm>};


на

#include <memory>

class B{
public:
  B() : a(new A()){
     throw "!!!";
  }
  ~B() {}
private:
    std::auto_ptr<A> a;
};


и почувствуй разницу
Re[3]: Сокрытие не-public членов классов
От: Аноним  
Дата: 24.01.03 08:35
Оценка:
Здравствуйте, Павел.
А можно объявить явную специализацию для деструктора и конструктора auto_ptr для incomplete type , а в скрытой реализации завершить определение типа и определить этот деструктор?
Не то чтобы мне нужно сделать подобную ерунду, просто интересно, можно ли так (видимо, с точки зрения стандарта — это все равно undefined behaviour — о чем Вы и говорили).
//user.h
template<class T>
class holder{
//something
private:
   std::auto_ptr<T>p_laja;
};

class Impl;
template<>
std::auto_ptr<Impl>::~auto_ptr();
//hidden.cpp
///definitions
Re[7]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 08:40
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>
ssm>#include <iostream>

ssm>struct A{
ssm>  char dummy[1000];
ssm>  static int count;
ssm>  A(){ count ++;}
ssm>  ~A(){ count --;}
ssm>};

ssm>int A::count = 0;

ssm>class B{
ssm>public:
ssm>  B() : a(new A()){
ssm>     throw "!!!";
ssm>  }
ssm>  ~B() {delete a;}
ssm>private:
ssm>  A * a;
ssm>};

ssm>
ssm>int main(){
ssm>  try{
ssm>    B b;  
ssm>  }
ssm>  catch(...)
ssm>  {
ssm>     std::cout << "Утечка памяти >= " << A::count * sizeof(A) << std::endl;
ssm>  }
ssm>}
ssm>


Такого на практике не будет
Все что нам нужно- обертка для какого-то класса. И выглядеть она будет вот так тривиально:

class B{
public:
    B()  { m_a = new A(); }
    ~B() { delete m_a; }
private:
    A * m_a;
};


То что ты говоришь- верно в том случае, если бы в классе B нужно было бы еще какие-то ресурсы получать. Исключение может возникнуть при создании A. И тогда деструктор не вызовится. Ну и отлично.
Задача этого класса B состоит только в создании/уничтожении класса A. Ну, правда, нужно туда (в B) еще добавить методы для доступа к методам класса A.
Re[8]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 08:50
Оценка:
Здравствуйте, Сray, Вы писали:

С>Такого на практике не будет

С>Все что нам нужно- обертка для какого-то класса. И выглядеть она будет вот так тривиально:

ну ты ведь 10 минут назад спрашивал зачем здесь auto_ptr<> твоя обертка — упрощенный до безобразия auto_ptr<>. вот ты сам и ответил на свой вопрос.

С>
С>class B{
С>public:
С>    B()  { m_a = new A(); }

а куда же ты throw "!!!" девал то?

С>    ~B() { delete m_a; }
С>private:
С>    A * m_a;
С>};
С>


С>То что ты говоришь- верно в том случае, если бы в классе B нужно было бы еще какие-то ресурсы получать. Исключение может возникнуть при создании A. И тогда деструктор не вызовится.


ну почему же только ресурсы? или генерить исключения умеет только operator new ?

С>Ну и отлично.


ню-ню

С>Задача этого класса B состоит только в создании/уничтожении класса A. Ну, правда, нужно туда (в B) еще добавить методы для доступа к методам класса A.


ну это же ведь все утрировано
Re[5]: Остерн
От: Fiend  
Дата: 24.01.03 09:03
Оценка:

but you couldn't write:

int illegal_function(my_class);

or:

my_class illegal_function();

struct illegal_class {
my_class f();
};

Интересно, Остерн имеет в виду, что я не могу определить эти функции? Для прототипа же необязателен полный тип?
Re[9]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 09:10
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>ну ты ведь 10 минут назад спрашивал зачем здесь auto_ptr<> твоя обертка — упрощенный до безобразия auto_ptr<>. вот ты сам и ответил на свой вопрос.


Вот! И я об этом! Все что я не понимал- зачем внутри класса выполняющего почти то-же что и auto_ptr нужен еще один auto_ptr.

С>>То что ты говоришь- верно в том случае, если бы в классе B нужно было бы еще какие-то ресурсы получать. Исключение может возникнуть при создании A. И тогда деструктор не вызовится.


ssm> ну почему же только ресурсы? или генерить исключения умеет только operator new ?


Да пусть кто хочет генерит. Не важно.

С>>Ну и отлично.


ssm>ню-ню


А вот этого не люблю.

С>>Задача этого класса B состоит только в создании/уничтожении класса A. Ну, правда, нужно туда (в B) еще добавить методы для доступа к методам класса A.


ssm>ну это же ведь все утрировано


И ничего не утрировано.
Все что фактически нужно- специализированный вариант auto_ptr в котором добавлены методы для доступа к методам класса A.
Конструктор-же может быть один к одному auto_ptr- ский.


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

вот твоя ссылка http://www.rsdn.ru/forum/Message.aspx?mid=167523&amp;only=1
Автор: Павел Кузнецов
Дата: 08.01.03


Тебе предогалось поменять
ssm>    std::auto_ptr<ImplType> impl_;

на
ImplType* impl_;
Re[6]: Остерн
От: Павел Кузнецов  
Дата: 24.01.03 09:17
Оценка:
Здравствуйте, Fiend, Вы писали:

F>

F>but you couldn't write:
F>int illegal_function(my_class);


F>Интересно, Остерн имеет в виду, что я не могу определить эти функции? Для прототипа же необязателен полный тип?


Верно, здесь маэстро не вполне точен :-) Кроме того, неточны и его высказывания относительно невозможности реализации шаблона std::map, не требующего для инстанциирования полного типа. Например, VC++7 + STLport 4.5.3 прекрасно компилирует следуюющее:

#include <map>

struct C;

struct D
{
  std::map<int, C> m;

  D();
  D(const D&);
  ~D();
};


Тем не менее, с исторической точки зрения, статья, ИМХО, интересна.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Сокрытие не-public членов классов
От: Павел Кузнецов  
Дата: 24.01.03 09:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А можно объявить явную специализацию для деструктора и конструктора auto_ptr для incomplete type


Можно.

А>а в скрытой реализации завершить определение типа и определить этот деструктор?


А вот тут возникает вполне закономерный вопрос: а как, собственно, ты сможешь определить деструктор или конструктор std::auto_ptr<>, "не зная" деталей реализации последнего?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Сокрытие не-public членов классов
От: Fiend  
Дата: 24.01.03 09:38
Оценка:
Ну, это... Я ведь только объявлю специализации, а определю их где-то в скрутой реализации, после после завершения определения типа. Ведь так-то можно?
Re[10]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 09:44
Оценка:
Здравствуйте, Сray, Вы писали:

С>Вот! И я об этом! Все что я не понимал- зачем внутри класса выполняющего почти то-же что и auto_ptr нужен еще один auto_ptr.


в том то все и дело, что он вообще не предназначен для єтого, единственная его задача — скрывать реализацию

С>А вот этого не люблю.

Твое право

С>>>Задача этого класса B состоит только в создании/уничтожении класса A. Ну, правда, нужно туда (в B) еще добавить методы для доступа к методам класса A.


ssm>>ну это же ведь все утрировано


С>И ничего не утрировано.

С>Все что фактически нужно- специализированный вариант auto_ptr в котором добавлены методы для доступа к методам класса A.
С>Конструктор-же может быть один к одному auto_ptr- ский.

С>

С>Кстати, я назад посты пролистал- так ты и сам предлагал заменить auto_ptr на простой указатель.
С>А теперь доказываешь что без auto_ptr не обойтись... Ты как-нибудь определись...

ты точно хорошо понимаешь, что такое pimpl ? помоему — несовсем. Я не предлагал использовать, я говорил, что использование auto_ptr<> c неполным типом по стандарту — UB

С>вот твоя ссылка http://www.rsdn.ru/forum/Message.aspx?mid=167523&amp;only=1
Автор: Павел Кузнецов
Дата: 08.01.03


ты все спутал Темой того
Автор: ssm
Дата: 08.01.03
топика было возможность написания шаблонного сласса template <class T> class ImplHolder, позволяющего скрыть реализацию для любого класс U порожденного от ImplHolder<T>, где T — класс реализации.

С>Тебе предогалось поменять

С>
ssm>>    std::auto_ptr<ImplType> impl_;
С>

С>на
С>
С>ImplType* impl_;
С>


Там — да, так и должно быть, но если ты заметил, этот топик отличаеться от того. Короче, там где видишь std::auto_ptr<T> читай его как свой менеджер для типа, не требующий полного описания T при инстанцировании. так понятно?
Re[6]: Сокрытие не-public членов классов
От: Павел Кузнецов  
Дата: 24.01.03 09:46
Оценка:
Здравствуйте, Fiend, Вы писали:

F>Ну, это... Я ведь только объявлю специализации, а определю их где-то в скрутой реализации, после после завершения определения типа.


И что ты там напишешь? Из стандарта нельзя вывести даже имя члена, для которого ты должен написать delete X :-) Если, например, для VC++, ты напишешь delete _Ptr, вовсе не факт, что твой деструктор скомпилируется с другой стандартной библиотекой. Например, в STLport 4.5.3 подобный член имеет имя _M_p.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Сокрытие не-public членов классов
От: Аноним  
Дата: 24.01.03 10:01
Оценка:
ААаа, ну это само собой.
Re[11]: Сокрытие не-public членов классов
От: Сray  
Дата: 24.01.03 10:12
Оценка:
Видимо, мы с вами на разных языках разговариваем.
Посему не вижу дальнейшего смысла продалжать с вами эту дискуссию.
Re[12]: Сокрытие не-public членов классов
От: ssm Россия  
Дата: 24.01.03 10:29
Оценка:
Здравствуйте, Сray, Вы писали:

С>Видимо, мы с вами на разных языках разговариваем.

С>Посему не вижу дальнейшего смысла продалжать с вами эту дискуссию.

Я Вам ее ненавязывал, поэтому Ваши мысли на этот счет, считаю более корректно, держать при себе. Если Вы с чем-либо несогласны, ставте 0 либо укажите то, с чем конкретно Вы несогласны.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.