LINUX.ORG.RU

Надо ли в конструкторе копирования вручную копировать все свойства класса?

 , класс,


0

1

Есть класс с большим количеством свойств. Нужно сделать для него конструктор копирования.

В моем случае, основное назначение конструктора копирования - это чтобы во включенных классах (несколько свойств у меня являются классами) обновить указатели на данный копируемый объект. Если этого не сделать, включенные классы будут хранить некорректные ссылки на размещение исходного объекта, а не скопированного.

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

Вопрос. Есть ли какая-нибудь возможность в конструкторе копирования одной командой скопировать все свойства, чтобы после нее прописать команды обновления ссылок?

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

★★★★★

Через memcpy можно скопировать, если не боишься :)

annulen ★★★★★
()

P.S. Класс с таким количеством свойств явно напрашивается на рефакторинг.

trex6 ★★★★★
()
Ответ на: комментарий от annulen

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

xaizek ★★★★★
()

Я не понимаю, почему топикстартер использует слово свойства? Свойствами обычно называют пары геттер+сеттер или их аналоги, которые с помощью синтаксического сахарка позволяют прямо писать class_name.property_name = foo, но при этом скрыто вызывают какой-то код, а не просто присваивают члену класса foo.

hlebushek ★★
()
Ответ на: комментарий от trex6

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

Stahl ★★☆
()
Ответ на: комментарий от annulen

Запихни все «простые» поля в структуру и копируй ее

Понять бы как это сделать.

То есть, вначале описать структуру чтобы получить тип. Это понятно.

Но как хранить в ней данные? Дублировать чтоли? Класс должен хранить значения как самих членов класса, так и значение этой структуры?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Но как хранить в ней данные? Дублировать чтоли?

Не понятно что именно вызывает вопросы. Простейший вариант - включить в класс поле с типов этой структуры. А можно и закрыто унаследоваться от неё.

Begemoth ★★★★★
()
Ответ на: комментарий от Xintrea

Как-то так

class A
{
public:
  A();
  A(const A &a);
  int x() const { return d.x; }
  void setX(int x) { d.x = x; }
  double y() const {return d.y;}
  void setY(double y) { d.y = y; }

// прочие объявления ...

private:
  struct Private {
    int x;
    double y;
    // и т.п.
  } d;

  B *b;
};

A::A(const A &a)
{
  b = new B(a.b);
  d = a.d;
}

annulen ★★★★★
()
Ответ на: комментарий от annulen

Упс, неправильно прочитал код. Звиняйте.

Gvidon ★★★★
()

Ну, если под рукой нормальный такстовый редактор, но просто скопировать объявления переменных и парочкой макросов ковертнуть их в присванивание не должно быть проблемой. Я вижу как это сделать в vim.

Но если совсем лень - я бы объявил «промежутосный» класс, содержащий только поля, с которыми справится дефолтный конструктор копрования, а от этого класса уже наследовал бы требуемый, добавляя поля, которые нельзя просто копировать. Тогда конструктор копирования твоего класса будет состоять из вызова конструктора копирования родительского + код для новый полей.

Но, ИМХО, макросами быстрее будет.

Kroz ★★★★★
()
Ответ на: комментарий от Begemoth

А можно и закрыто унаследоваться от неё.

Вот так что ли?

struct FooProperties {
    int x;
    string y;
    ...
}

class Foo;

struct Bar {
    Foo* mFoo;
}

class Foo : private FooProperties {
public:
    Foo (const Foo& other) 
        : FooProperties (other) {
        mBar.mFoo = this;
    }
    getFoo () { return mFoo }
    ...
private:
    Bar mBar;
}

jeuta ★★★★
()
Последнее исправление: jeuta (всего исправлений: 1)
Ответ на: комментарий от annulen

b = new B(a.b);

b = new B(*a.b);
?

ТС: можно также воспользоваться QSharedData и QSharedDataPointer/QExplicitlySharedDataPointer - заодно упростишь управление памятью
http://doc.qt.io/qt-4.8/qshareddatapointer.html - там хороший пример.

dib2 ★★★★★
()
Ответ на: комментарий от DELIRIUM

Причем здесь в лоб и быстрее? Чел явно хочет ничего не забыть, когда в след.раз ему стрельнет поменять структуру.

anonymous
()

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

javaQest
()
Ответ на: комментарий от DELIRIUM

Ты бы написал этот конструктор копипастом в лоб быстрее, чем набирал этот пост

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от javaQest

19 дней без бана за тупняк. твой личный рекорд :D

anonymous
()
Ответ на: комментарий от hlebushek

в этих ваших говноRADах это «обычно» называют «свойствами». а изначально в ООП-парадигме так назывались характеристики объекта («поля данных в экземпляре класса», если пользоваться вашей говнотерминологией).

anonymous
()

Первое, что надо сделать - подумать, нужны ли тебе указатели. Если нужны, то может имеет смысл использовать shared_ptr? Может и твоя проблема пропадет сама собой.

invy ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.