2010-10-03 11 views
3

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

Но может кто-нибудь объяснить, почему компилятор делает это?

Что произойдет, если копия ctor объявлена ​​защищенной? Будет ли компилятор предоставлять копию по умолчанию ctor?

Что произойдет, если копия ctor объявлена ​​приватной, но имеет определение, например. foo (const & obj) {}

ответ

4

Любой конструктор копирования, объявленный в классе (будь он закрытый, общедоступный или защищенный), означает, что компилятор не будет генерировать копию ctor по умолчанию. Является ли тот, объявленный в классе, тогда также определенным или не только контролирует, может ли код с надлежащим уровнем видимости в него копировать экземпляры класса (если не определено, то компоновщик будет жаловаться, а работа компилятора должна только жаловаться на использование без надлежащей видимости, чтобы не дублировать работу компоновщика).

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

2

Компилятор знает, что существует конструктор копирования, поэтому он не будет генерировать его. Доступность (общедоступная/конфиденциальная/защищенная) или ее определение не рассматривается на этом этапе.

Похоже, что нет конструктора копий только потому, что вы не можете вызвать частную функцию извне и не друзьями. Пользовательский конструктор все еще существует, только тот, который является частным.

Если он защищен, тогда только подклассы и сам могут вызвать конструктор копирования. Не будет и неявно определенных конструкторов копирования.

0

Компилятор не будет генерировать конструктор копии по умолчанию всякий раз, когда конструктор копирования объявлен явно. Это верно независимо от того, какой уровень конфиденциальности (закрытый, защищенный или открытый) имеет явное объявление.

1

$ 12/1 - «конструктор по умолчанию (12,1), конструктор копирования и копирование оператора присваивания (12.8) и деструктора (12.4) являются специальным членом функции [Примечания: Реализация будет. неявно объявить эти член функции для некоторых типов классов, когда программы не явно объявить их. реализация будет неявно определить их, если они используется. [...]»

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

Конструктор копирования может быть объявлен и определен как закрытый. Если конструктор копирования определен как закрытый, инициализация копирования/прямая инициализация не будут работать, как показано ниже.

struct A{ 
    A(){} 
private: 
    A(A const &){} 
}; 

int main(){ 
    A a1; 
    A a2(a1); // direct initialization, error 

    A a3 = a1; // copy initialization, error 
} 
Смежные вопросы