Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие
m_field_val = Instance.m_field_val;
Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается).
Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень).
Re: Громоздкость перегрузки конструктора копирования (и оператора присваивания)
Здравствуйте, _hum_, Вы писали:
__>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>
__>m_field_val = Instance.m_field_val;
__>
__>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается).
__>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
__>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень).
Можно сделать такое с помощью boost::fusion::for_each, предварительно адаптировав класс макросом вроде BOOST_FUSION_ADAPT_STRUCT. Например нужно сделать некоторые покомпонентные операции с большой структурою:
Здравствуйте, _hum_, Вы писали:
__>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>
__>m_field_val = Instance.m_field_val;
__>
А почему бы все эти поля просто убрать в структуру без всяких перегрузок и использовать что-то вроде такого:
data = Instance.data
?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Громоздкость перегрузки конструктора копирования (и оператора присваивания)
Здравствуйте, _hum_, Вы писали:
__>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
Хехе, а вот в Аде там по умолчанию при копировании сначала делается простое побитовое копирование, потом для всех полей вызывается метод Adjust, а потом уже для самого класса вызывается метод Adjust. И да, писать почти одно и то же два раза (я про конструктор копирования и оператор =) в ней не надо,
Но это же противоречит принципу "не платить за то, что не заказывал", хотя экономия тут полторы спички.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: Громоздкость перегрузки конструктора копирования (и оператора присваивания)
Здравствуйте, _hum_, Вы писали:
__>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
Давно существует:
MyClass& MyClass::operator=(const MyClass& rObj)
{
if( this != &rObj )
{
this->~MyClass();
new (this) MyClass(rObj);
}
return *this;
}
но я почему-то страшусь таких конструкций.
И каждый день — без права на ошибку...
Re[2]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _hum_, Вы писали:
__>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
BFE>Давно существует:
ТС не то спрашивал.
Но я так и делаю, как ты написал.
Конструктор копирования должен быть ноэксепт для этого, конечно.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Warturtle, Вы писали:
W>Здравствуйте, _hum_, Вы писали:
__>>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>>
__>>m_field_val = Instance.m_field_val;
__>>
__>>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается).
__>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
__>>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень). W>Можно сделать такое с помощью boost::fusion::for_each, предварительно адаптировав класс макросом вроде BOOST_FUSION_ADAPT_STRUCT. Например нужно сделать некоторые покомпонентные операции с большой структурою: W>
Здравствуйте, _hum_, Вы писали:
__>да, но, если я правильно понял, все равно приходится ручками работать — перечислять все нужные поля в макросе адаптации
Подожди ещё лет 10, и дохлый страус наконец-то добавит рефлексию времени компиляции, и потом ещё 5, и она появится в Студии, и ещё 5, и новая Студия перестанет глючить.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _hum_, Вы писали:
__>>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>>
__>>m_field_val = Instance.m_field_val;
__>>
V>А почему бы все эти поля просто убрать в структуру без всяких перегрузок и использовать что-то вроде такого: V>
V>data = Instance.data
V>
V>?
потому что, во-первых, это техническая структура, а во-вторых, если поля связаны между собою (например, объект одного поля имеет ссылки на объект другого поля за пределами data), то все еще больше усложнится. уж лучше тогда обернуть указатели в какие-нибудь смарт-поинтеры, которые автоматически при копировании клонируют свои объекты (кстати, а такого плана умные указатели вообще существуют, например, в том же бусте?).
Re[2]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
TB>Хехе, а вот в Аде там по умолчанию при копировании сначала делается простое побитовое копирование, потом для всех полей вызывается метод Adjust, а потом уже для самого класса вызывается метод Adjust.
во-во. что-то похожее хотелось бы организовать
TB> И да, писать почти одно и то же два раза (я про конструктор копирования и оператор =) в ней не надо,
так в с++ тоже во многих случаях (хотя и не всегда) копирование можно через присваивание определить:
CopyCtr(const CopyCtr& Inst)
{
operator=(Inst);
}
Re[2]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _hum_, Вы писали:
__>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
BFE>Давно существует: BFE>
да, это немного не то — это как определить присваивание через конструктор копирования
кста, давече по поводу placement new натолкнулся на строгое предупреждение — мол, вам никто не гарантирует, что объект будет размещен именно с начала указателя на буфер. при размещении могут еще учитываться всякие выравнивания и проч.
потому я бы тоже побоялся такое использовать.
Re[3]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали: __>кста, давече по поводу placement new натолкнулся на строгое предупреждение — мол, вам никто не гарантирует, что объект будет размещен именно с начала указателя на буфер. при размещении могут еще учитываться всякие выравнивания и проч. __>потому я бы тоже побоялся такое использовать.
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>да, но, если я правильно понял, все равно приходится ручками работать — перечислять все нужные поля в макросе адаптации
TB>Подожди ещё лет 10, и дохлый страус наконец-то добавит рефлексию времени компиляции, и потом ещё 5, и она появится в Студии, и ещё 5, и новая Студия перестанет глючить.
а в новом стандарте ничего по этому поводу не придумали? я слышал, там какие-то новшества вводили, связанные с дефолтными конструкторами и операторами присваивания. вот и надеялся, что может, и эту проблему разрулили.
Re[4]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали: __>>кста, давече по поводу placement new натолкнулся на строгое предупреждение — мол, вам никто не гарантирует, что объект будет размещен именно с начала указателя на буфер. при размещении могут еще учитываться всякие выравнивания и проч. __>>потому я бы тоже побоялся такое использовать.
TB>Ну дык нефиг невыровненные указатели использовать.
извиняюсь, а как в с++ можно удостовериться, что они выровнены нужным образом?
и еще, это единственное условие, или еще какие-то есть на корректность использования placement new?
Re[4]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>так в с++ тоже во многих случаях (хотя и не всегда) копирование можно через присваивание определить: __>>
Здравствуйте, _hum_, Вы писали:
__>>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования? __>да, это немного не то — это как определить присваивание через конструктор копирования
А, чёрт! Дак это, делегирующие конструкторы вам в помощь.
И каждый день — без права на ошибку...
Re[5]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, _hum_, Вы писали:
__>извиняюсь, а как в с++ можно удостовериться, что они выровнены нужным образом?
Ну можно завести структуру CheckAlign{ char c; MyClass obj; }, тогда sizeof(CheckAlign)-sizeof(MyClass) будет выравниванием, осталось проверить, что значение указателя делится на это выравнивание.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[5]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>зачем? присваивание и есть инициализация.
Затем, что присваивание не инициализация. Присваивание ещё и смотрит на то, что было в объекте до этого. Например, в умном указателе, такой утрированный пример:
Поэтому очень важно, чтобы перед вызовом = объект находился в самосогласованном состоянии. Вызов пустого конструктора это и делает.
__>п.с. и вообще код __>
Здравствуйте, T4r4sB, Вы писали:
__>>кста, давече по поводу placement new натолкнулся на строгое предупреждение — мол, вам никто не гарантирует, что объект будет размещен именно с начала указателя на буфер. при размещении могут еще учитываться всякие выравнивания и проч. __>>потому я бы тоже побоялся такое использовать.
TB>Ну дык нефиг невыровненные указатели использовать.
А разве this может быть неправильно выровнен ?
И каждый день — без права на ошибку...
Re[5]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, _hum_, Вы писали:
__>>>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования? __>>да, это немного не то — это как определить присваивание через конструктор копирования
BFE>А, чёрт! Дак это, делегирующие конструкторы вам в помощь.
вроде, не поможет, ибо непонятно, как вызвать дефолтный конструктор. запись наподобие
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>извиняюсь, а как в с++ можно удостовериться, что они выровнены нужным образом?
TB>Ну можно завести структуру CheckAlign{ char c; MyClass obj; }, тогда sizeof(CheckAlign)-sizeof(MyClass) будет выравниванием, осталось проверить, что значение указателя делится на это выравнивание.
а кто гарантирует, что компилятор выравнивание для obj внутри CheckAlign и для obj самого по себе делает одинаково?
Re[7]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
__>>разве пройдет?
BFE>Да. Это нововведение С++11. см. здесь
аа, это, типа, делегирующий конструктор.
так а все-таки, он нужен (по-хорошему, должен применяться) при определении конструктора копирования через присваивание или не обязательно?
Re[3]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>уж лучше тогда обернуть указатели в какие-нибудь смарт-поинтеры, которые автоматически при копировании клонируют свои объекты (кстати, а такого плана умные указатели вообще существуют, например, в том же бусте?).
тогда непонятно зачем вообще эти смарт поинтеры держать, а не положить сам объект в класс по значению а не ссылке/указателю.
Если они не копируемые, то вам и такой смарт поинтер ничем не поможет, т.к. опять не будет компилироваться из-за запрета на копирование. А если объект клонируемый, то обычно делают отдельную функцию создания/копирования и тогда не понятно как такой смартпоинтер должен быть генерализован, потому-что как правило функция клонирования уже использует смарт поинтер для возврата объекта. Проще тогда просто создавать класс объекта+смарт поинтер вокруг него с блекджеком и ...
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: Громоздкость перегрузки конструктора копирования (и о
__>аа, это, типа, делегирующий конструктор. __>так а все-таки, он нужен (по-хорошему, должен применяться) при определении конструктора копирования через присваивание или не обязательно?
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>зачем? присваивание и есть инициализация.
TB>Затем, что присваивание не инициализация. Присваивание ещё и смотрит на то, что было в объекте до этого. Например, в умном указателе, такой утрированный пример:
TB>
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _hum_, Вы писали:
__>>уж лучше тогда обернуть указатели в какие-нибудь смарт-поинтеры, которые автоматически при копировании клонируют свои объекты (кстати, а такого плана умные указатели вообще существуют, например, в том же бусте?). V>тогда непонятно зачем вообще эти смарт поинтеры держать, а не положить сам объект в класс по значению а не ссылке/указателю.
я же писал в самом начале:
__>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень).
V>Если они не копируемые, то вам и такой смарт поинтер ничем не поможет, т.к. опять не будет компилироваться из-за запрета на копирование.
чего ж запрета то? я же не про unique_ptr вел речь, а про некий обобщенный смарт-поинтер, который умеет копироваться, и при копировании копирует еще и объект, на который указывает образец.
Re: Громоздкость перегрузки конструктора копирования (и оператора присваивания)
Здравствуйте, _hum_, Вы писали:
__>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается). __>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования? __>...а создавать отдельный копируемый класс для него как-то лень...
Думаю, что создать отдельный класс для копируемых полей будет самым практичным. Да там и писать будет всего ничего.
Re[5]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>чего ж запрета то? я же не про unique_ptr вел речь, а про некий обобщенный смарт-поинтер, который умеет копироваться, и при копировании копирует еще и объект, на который указывает образец.
при клонировании конструктор копирования обычно прикрывают.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[8]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>аа, это, типа, делегирующий конструктор. __>>так а все-таки, он нужен (по-хорошему, должен применяться) при определении конструктора копирования через присваивание или не обязательно?
TB>Можно без него, в ++03 можно так: TB>
угу. токо так не всегда удобно делать, если, например, код инициализации должен быть гарантированно вызван только один раз — при конструировании объекта.
Re[9]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, _hum_, Вы писали:
__>угу. токо так не всегда удобно делать, если, например, код инициализации должен быть гарантированно вызван только один раз — при конструировании объекта.
А где он у меня вызывается два раза?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[5]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>я же писал в самом начале: __>>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень).
ну положите оффсеты относительно базы, зачем там именно поинтеры на this? чтобы осложнить себе жизнь?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[6]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _hum_, Вы писали:
__>>чего ж запрета то? я же не про unique_ptr вел речь, а про некий обобщенный смарт-поинтер, который умеет копироваться, и при копировании копирует еще и объект, на который указывает образец. V>при клонировании конструктор копирования обычно прикрывают.
может, я неудачно термин употребил, но под клонированием я понимал создание точной копии объекта. так что смысла прятать конструктор копирования как бы нет.
грубо горя, ситуация типа такой:
enum KINDs{kind_a, kind_b};
class CAbstactItem
{
virtual KINDs kind_of()= 0;
};
class CItemA : public CAbstactItem{ //<implementation>};class CItemB : public CAbstactItem{ //<implementation>};class CFoo
{
//<100500 копируемых полей>
std::vector<CAbstactItem*> m_ItemsStock;
};
и нужно организовать возможность копирования объектов класса CFoo при условии, что CItemA и CItemB сами по себе copyable
Re[6]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _hum_, Вы писали:
__>>я же писал в самом начале: __>>>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень). V>ну положите оффсеты относительно базы, зачем там именно поинтеры на this? чтобы осложнить себе жизнь?
вы о чем. какие оффсеты?
Re[10]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>угу. токо так не всегда удобно делать, если, например, код инициализации должен быть гарантированно вызван только один раз — при конструировании объекта.
TB>А где он у меня вызывается два раза?
у вас нигде. но никто не запрещает это сделать в любом месте и по многу раз
Re[3]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, B0FEE664, Вы писали:
BFE>>Здравствуйте, _hum_, Вы писали:
__>>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
BFE>>Давно существует:
TB>ТС не то спрашивал. TB>Но я так и делаю, как ты написал. TB>Конструктор копирования должен быть ноэксепт для этого, конечно.
а где вам такое приходится делать? не проще ли все-таки конструктор копирования через оператор присваивания определять?
Re[7]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>>>я же писал в самом начале: __>>>>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень). V>>ну положите оффсеты относительно базы, зачем там именно поинтеры на this? чтобы осложнить себе жизнь? __>вы о чем. какие оффсеты?
у вас m_ItemsStock куда указывает, как выделены объекты в нём?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, _hum_, Вы писали:
__>>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается). __>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования? __>>...а создавать отдельный копируемый класс для него как-то лень...
К>Думаю, что создать отдельный класс для копируемых полей будет самым практичным. Да там и писать будет всего ничего.
уверены? а как насчет, например, воспроизведения такой последовательности инициализации:
class CFoo
{
const CA m_A;//copyableconst CB m_B;//non-copyableconst CC m_C;//copyable
CFoo():m_A(100), m_B(m_A), m_C(m_B){}
};
Re[8]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _hum_, Вы писали:
__>>>>я же писал в самом начале: __>>>>>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень). V>>>ну положите оффсеты относительно базы, зачем там именно поинтеры на this? чтобы осложнить себе жизнь? __>>вы о чем. какие оффсеты? V>у вас m_ItemsStock куда указывает, как выделены объекты в нём?
int i;
std::cin>>i;
const bool b = (0 == i % 2);
m_ItemsStock[0] = b ? (new CItemA()) : (new CItemB());
m_ItemsStock[1] = b ? (new CItemB()) : (new CItemA());;
Re[4]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>а где вам такое приходится делать? не проще ли все-таки конструктор копирования через оператор присваивания определять?
Не знаю, может и проще. Мне сама идея не нравится тем, что предъявляет к объекту дополнительное требование: "нулевое состояние".
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[5]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, _hum_, Вы писали:
__>>а где вам такое приходится делать? не проще ли все-таки конструктор копирования через оператор присваивания определять?
TB>Не знаю, может и проще. Мне сама идея не нравится тем, что предъявляет к объекту дополнительное требование: "нулевое состояние".
так вы же сами предложили способ, как от этого избавиться — использовать делегированный конструктор. это уж лучше, чем требования всяких выровненностей.
Re[9]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
__>int i;
__>std::cin>>i;
__>const bool b = (0 == i % 2);
__>m_ItemsStock[0] = b ? (new CItemA()) : (new CItemB());
__>m_ItemsStock[1] = b ? (new CItemB()) : (new CItemA());;
__>
а эти классы обязательно через new создавать?
std::vector<boost::any> m_ItemsStock;
b ? m_ItemsStock.push_back(CItemA()) : m_ItemsStock.push_back(CItemB());
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, _hum_, Вы писали:
__>>>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается). __>>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования? __>>>...а создавать отдельный копируемый класс для него как-то лень... К>>Думаю, что создать отдельный класс для копируемых полей будет самым практичным. Да там и писать будет всего ничего.
__>уверены? а как насчет, например, воспроизведения такой последовательности инициализации:
__>
__>class CFoo {
__> // мышка за кошку
__> // кошка за Жучку
__> // Жучка за внучку
__> // внучка за бабку
__> // бабка за дедку
__> // дедка за репку
__>};
__>
Может лучше привести пример кода близкий к реальному? Или у вас в коде на самом деле всё так плохо, как в примере?
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _hum_, Вы писали:
__>>
__>>int i;
__>>std::cin>>i;
__>>const bool b = (0 == i % 2);
__>>m_ItemsStock[0] = b ? (new CItemA()) : (new CItemB());
__>>m_ItemsStock[1] = b ? (new CItemB()) : (new CItemA());;
__>>
V>а эти классы обязательно через new создавать? V>
интересная штука этот паттерн "variant" (кстати, некое подобие смарт-поинтера, о котором я выше вел речь). но ведь тогда, чтобы вызвать виртуальную функцию, придется писать вместо
m_ItemsStock[i]->virt_fun();
что-то наподобие
((CAbstactItem&)(m_ItemsStock[i])).virt_fun();
или того хуже — switch-case. нет?
Re[4]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, _hum_, Вы писали:
__>>>>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается). __>>>>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования? __>>>>...а создавать отдельный копируемый класс для него как-то лень... К>>>Думаю, что создать отдельный класс для копируемых полей будет самым практичным. Да там и писать будет всего ничего.
__>>уверены? а как насчет, например, воспроизведения такой последовательности инициализации:
__>>
__>>class CFoo {
__>> // мышка за кошку
__>> // кошка за Жучку
__>> // Жучка за внучку
__>> // внучка за бабку
__>> // бабка за дедку
__>> // дедка за репку
__>>};
__>>
К>Может лучше привести пример кода близкий к реальному? Или у вас в коде на самом деле всё так плохо, как в примере?
я лишь хотел показать, что есть подводные камни, и не все так просто, как кажется.
а ситуация, когда объекты взаимодействуют между собой (а значит, должны инициализироваться в строгой последовательности), по-моему, сплошь и рядом.
Re[11]: Громоздкость перегрузки конструктора копирования (и оператора присваиван
Здравствуйте, B0FEE664, Вы писали:
TB>>Ну дык нефиг невыровненные указатели использовать. BFE>А разве this может быть неправильно выровнен ?
Видимо он может быть по-разному выровнен, к примеру, на стеке и в хипе. На хипе обычно делают выравнивание с запасом. На стеке, только до необходимой величины.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Громоздкость перегрузки конструктора копирования (и оператора присваивания)
Здравствуйте, _hum_, Вы писали:
__>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>
__>m_field_val = Instance.m_field_val;
__>
[злая_шутка]
memcpy(this, &Instance, sizeof (*this));
[/злая_шутка]
я за идею создания класса-шаблона автокопируемых полей. С++ тем и хорош: 1. там нет лишнего. 2. любое нужное можно сделать.
Re[6]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, Vain, Вы писали:
V>Видимо он может быть по-разному выровнен, к примеру, на стеке и в хипе. На хипе обычно делают выравнивание с запасом. На стеке, только до необходимой величины.
Ну и что плохого этот запас сделает? Плацемент по-другому сработает?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[12]: Громоздкость перегрузки конструктора копирования (и оператора присваиван
Здравствуйте, CEMb, Вы писали:
CEM>Здравствуйте, _hum_, Вы писали:
__>>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>>
__>>m_field_val = Instance.m_field_val;
__>>
CEM>[злая_шутка] CEM>
CEM>memcpy(this, &Instance, sizeof (*this));
CEM>
[/злая_шутка]
CEM>я за идею создания класса-шаблона автокопируемых полей. С++ тем и хорош: 1. там нет лишнего. 2. любое нужное можно сделать.
что за идея-то? создание отденьного класса,в который помещаются все копируемые поля? так уже выше обсуждалось, почему это не всегда возможно. или имелась в виду идея обертки каждого некопируемого класса в делающий его копируемым класс?
Re[3]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>или имелась в виду идея обертки каждого некопируемого класса в делающий его копируемым класс?
ага. Не для каждого, а просто дефайн-шаблон написать. Ну и класс-контейнер таких итемов должен иметь функционал для работы с такими штуками.
Хотя, на вскидку, решение простое не получится... Но задачка интересная Т.е. при объявлении, как-то надо суметь их или внести в список. Или в операторе копирования уметь их находить в классе и вызывать их оператор копирования.
Re[5]: Громоздкость перегрузки конструктора копирования (и о
Здравствуйте, _hum_, Вы писали:
__>>>уверены? а как насчет, например, воспроизведения такой последовательности инициализации:
__>>>
__>>>class CFoo {
__>>> // мышка за кошку
__>>> // ...
__>>> // дедка за репку
__>>>};
__>>>
К>>Может лучше привести пример кода близкий к реальному? Или у вас в коде на самом деле всё так плохо, как в примере?
__>я лишь хотел показать, что есть подводные камни, и не все так просто, как кажется. __>а ситуация, когда объекты взаимодействуют между собой (а значит, должны инициализироваться в строгой последовательности), по-моему, сплошь и рядом.
Я исходил для типичного для нашего кода случая, когда члены класса инициализируются независимо.
Ситуации, когда инициализация одних членов класса завязана на другие члены класса, у нас встречается редко. Пусть тот кто так написал сам и страдает
Re[3]: Громоздкость перегрузки конструктора копирования (и оператора присваивани
Здравствуйте, _hum_, Вы писали:
__>Здравствуйте, Warturtle, Вы писали:
W>>... __>да, но, если я правильно понял, все равно приходится ручками работать — перечислять все нужные поля в макросе адаптации
Ну если класс свой, а не из заголовков какой-то библиотеки, то можно перечислить поля лишь однажды.
Re: Громоздкость перегрузки конструктора копирования (и оператора присваивания)
Здравствуйте, _hum_, Вы писали:
__>Появились ли к настоящему моменту какие-нибудь эффективные способы написания перегрузок для соответствующих методов, позволяющие сократить до минимума тупое перечисление наподобие __>
__>m_field_val = Instance.m_field_val;
__>
Это невозможно, пока в языке нет поддержки рефлексии времени компиляции. Есть только костыль в виде boost.fusion
__>Например, если в классе очень много копируемых полей, и очень мало указателей (unique owners), то такое перечисление выглядит очень дико (к тому же вероятность пропустить, не дописать и т.п. многократно увеличивается).
Наверняка эти unique_ptr там не спроста. Меня в таком случае обычно устраивает некопируемость класса (в C++11 он может быть при этом перемещаемым)
__>Может, появилась какая-нить возможность принудительно вызывать конструктор копирования по умолчанию внутри перегрузки конструктора копирования?
__>На всякий случай — у меня внутри класса гетерогенный контейнер (контейнер указателей на базовый класс, от которого наследуются разные классы объектов). Соответственно, именно для него приходится ручками писать копирование (а создавать отдельный копируемый класс для него как-то лень).
Здравствуйте, PM, Вы писали:
PM>Ещё один способ иногда пригодный для плоских иерархий — использовать variant и variant visitor для создания полиморфного интерфейса
Класс. Это так теперь паттерн-матчинг называется?
Есть ещё https://github.com/solodon4/Mach7 макросами, темплейтами и какой-то матерью сделан почти вменяемый pattern-matching.
На самом деле их писать не нужно — только ошибок понаделаете и отключите заодно генерацию move конструкторов.
Члены класса должны сами знать как себя копировать. Тогда автоматически сгенерированные конструкторы окажутся подходящими.
Перегружать копирование редко нужно только для утилитарных классов типа shared_ptr.
--
Если совсем никак не обойтись, можно покурить такую тему (C++11):
class Copy
{
public:
Copy() {}
Copy(const Copy& it) : Copy()
{
*this = it;
.. add here your specific 'copy adjust' code ..
}
protected:
void operator=(const other& it) = default;
Re[2]: Любопытно,наверно,такая конструкция будет работать внутри наследованного
J>На самом деле их писать не нужно — только ошибок понаделаете и отключите заодно генерацию move конструкторов. J>Члены класса должны сами знать как себя копировать. Тогда автоматически сгенерированные конструкторы окажутся подходящими.
J>Перегружать копирование редко нужно только для утилитарных классов типа shared_ptr.
J>--
J>Если совсем никак не обойтись, можно покурить такую тему (C++11): J>
это почти что нужно, за исключение одного НО — как в вашем варианте определить еще и свой оператор присваивания (ведь если задача требует определения своего конструктора копирования, то нельзя оставлять "нэйтивный" оператор присваивания)?