Здравствуйте, Константин, Вы писали:
К>Здравствуйте, _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;