Рекомендации по конструктору копирования класса, содержащего не копируемую ссылку на член - PullRequest
2 голосов
/ 27 июля 2011

У меня есть класс A, который имеет ссылку на объект класса B в качестве члена.Конструктор копирования (и оператор присваивания) класса B является закрытым.Считаете ли вы правильным и хорошей идеей использовать конструктор копирования по умолчанию для A. (На самом деле мне нужна функциональность, в которой я могу хранить множество объектов для типа A в каком-то контейнере STL, который требует как назначений, так ивозможность копирования.)

class A
{
    private:
        B& b_;

    public:
        A(B& b) : b_(b){}
}

До сих пор, насколько мне известно, возражения против вышеуказанного метода следующие, но мой дизайн не с этим сталкивается.Я хотел бы знать, есть ли какие-либо другие проблемы / проблемы / проблемы в приведенном выше примере ...

  1. Копируется только ссылка, и, следовательно, будут проблемы, когда исходный объект b типаБ уничтожен.(Не применяется, поскольку b доступен во всей области видимости.)
  2. Является ли b_ уникальным для каждого экземпляра A?(Нет, B фактически создается только один раз в области видимости, поэтому он имеет эффект одноэлементного класса.)

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

Ответы [ 4 ]

2 голосов
/ 27 июля 2011

Как правило, я никогда не храню ссылки внутри объектов, потому что не могу получить семантику копирования бесплатно.

Вместо этого я храню указатели.Здесь, хранение тупого указателя и предоставление компилятору возможности реализовать семантику копирования для вас выглядит вполне нормально:

class A
{
    B* b; // or a smart pointer, depending on what semantics you want.

public:
    A(B& b) : b(&b) {}
};

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

2 голосов
/ 27 июля 2011

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

0 голосов
/ 27 июля 2011

Если оператор присваивания B является приватным, то компилятор не может сгенерировать по умолчанию оператор assignemnt для A. Вам нужно будет явно объявить оператор присваивания. В противном случае вы получите ошибку компиляции : http://msdn.microsoft.com/en-us/library/aa983787%28v=vs.71%29.aspx

Как только вы это сделаете, у вас не должно возникнуть проблем, поместите объект A в контейнер STL.

0 голосов
/ 27 июля 2011

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

В качестве стороныобратите внимание, я рекомендую сделать конструктор A(B&) явным, чтобы неявно трактовать B как A.

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