CFile проблемы

shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

CFile проблемы

Post by shadow7256 »

Есть такая конструкция

class A
{
public:
A ();

private:
CFile file;
}

при компиляции выскакивает ошибка "класс А не имеет конструктора копирования". Как только убираю CFile из переменных классса А, то все нормально. Даже если явно добавлю констуктор копирования, то все равно вылетает ошибка.
Hamster
Уже с Приветом
Posts: 11475
Joined: 20 Nov 2000 10:01
Location: Escondido, CA

Re: CFile проблемы

Post by Hamster »

shadow7256 wrote: Даже если явно добавлю констуктор копирования, то все равно вылетает ошибка.


Ошибка в чем-то другом, приведите весь код.
shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

Post by shadow7256 »

как только я заменил объект клааса CFile на указатель на объект класса CFile то все стало нормально :pain1:
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

shadow7256 wrote:как только я заменил объект клааса CFile на указатель на объект класса CFile то все стало нормально :pain1:


А почему это вас удивляет? Обьект и указатель это настолько разные вещи ...

У вас там нигде нет чего-нибудь типа:

Code: Select all

A var1;
A var2;

var2 = var1;
User avatar
AndreyT
Уже с Приветом
Posts: 3000
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

shadow7256 wrote:как только я заменил объект клааса CFile на указатель на объект класса CFile то все стало нормально :pain1:


Класс 'CFile' не имеет доступного конструктора копирования. По этой причине компилятор не имеет возможности сгенерировать конструктор копирования и для класса 'A'. А ты его где-то пытаешься использовать. Это и приводит к ошибке.

1) Либо прекрати использовать конструктор копирования класса 'A'

2) Либо определи конструктор копирования для класса 'A' руками.

3) Либо сделай так, чтобы компилятор мог сгенерировать осмысленный конструктор копирования для класса 'A'.

Замена на указатель - это шаг в направлении третьего решения. Насколько это осмысленный шаг - зависит от конкретной задачи. Деталей ты тут не даешь, поэтому ничего конкретного сказать нельзя.
Best regards,
Андрей
User avatar
AndreyT
Уже с Приветом
Posts: 3000
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

KVA wrote:У вас там нигде нет чего-нибудь типа:

Code: Select all

A var1;
A var2;

var2 = var1;


К конструкторам копирования такой код никакого отношения не имеет. Скорее тогда

Code: Select all

A var1;
A var2 = var1;
Best regards,
Андрей
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

AndreyT wrote:
KVA wrote:У вас там нигде нет чего-нибудь типа:

Code: Select all

A var1;
A var2;

var2 = var1;


К конструкторам копирования такой код никакого отношения не имеет. Скорее тогда

Code: Select all

A var1;
A var2 = var1;


Имеет, имеет. Где можна, везде компилятор всунет копи-констрактор вместо присваивания.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

AndreyT wrote:К конструкторам копирования такой код никакого отношения не имеет. Скорее тогда


Ну да в общем ...
User avatar
AndreyT
Уже с Приветом
Posts: 3000
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

A. Fig Lee wrote:
AndreyT wrote:
KVA wrote:У вас там нигде нет чего-нибудь типа:

Code: Select all

A var1;
A var2;

var2 = var1;


К конструкторам копирования такой код никакого отношения не имеет. Скорее тогда

Code: Select all

A var1;
A var2 = var1;


Имеет, имеет. Где можна, везде компилятор всунет копи-констрактор вместо присваивания.


Ни в коем случае. Присваивание в такой ситуации выполняется только оператором присваивания. Инициализация - только конструктором. Деление совершенно четкое и однозначное.
Best regards,
Андрей
shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

Post by shadow7256 »

AndreyT wrote:Класс 'CFile' не имеет доступного конструктора копирования. По этой причине компилятор не имеет возможности сгенерировать конструктор копирования и для класса 'A'.


Андрей, я не совсем понимаю здесь связь. Если член класса А ,который в свое очередь сам является каким то другим классом (CFile в моем случае), не имеет конструктора копирования, то каким образом это связано с конструктором коппирования самого класса А?


2) Либо определи конструктор копирования для класса 'A' руками.


определял, не помогло.

Замена на указатель - это шаг в направлении третьего решения. Насколько это осмысленный шаг - зависит от конкретной задачи. Деталей ты тут не даешь, поэтому ничего конкретного сказать нельзя.


Указатель в моем случае нормально.
User avatar
AndreyT
Уже с Приветом
Posts: 3000
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

shadow7256 wrote:
AndreyT wrote:Класс 'CFile' не имеет доступного конструктора копирования. По этой причине компилятор не имеет возможности сгенерировать конструктор копирования и для класса 'A'.


Андрей, я не совсем понимаю здесь связь. Если член класса А ,который в свое очередь сам является каким то другим классом (CFile в моем случае), не имеет конструктора копирования, то каким образом это связано с конструктором коппирования самого класса А?


Когда у класса нет явно объявленного конструктора копирования, компилятор объявляет его сам, неявно, как public член. Более того, если этот конструктор копирования используется в программе, то компилятор еще и неявно определяет этот конструктор. Встает вопрос: как он его определяет? А определяет он его очень просто - просто выполняет почленное копирование всех подобъектов данного класса, вызвая по очереди их конструкторы копирования.

Именно это происходит в твоем случае. Пытаясь сгенерировать конструктор копирования для 'A', компилятор хочет вызвать конструктор копирования 'CFile'. Но у класса 'CFile' нет доступного конструктора копирования, поэтому компилятор не может выполнить такого неявного определения. Возникает ошибка.

2) Либо определи конструктор копирования для класса 'A' руками.


определял, не помогло.


Значит ты что-то неправильно определял. Покажи, как ты это делал.

Замена на указатель - это шаг в направлении третьего решения. Насколько это осмысленный шаг - зависит от конкретной задачи. Деталей ты тут не даешь, поэтому ничего конкретного сказать нельзя.


Указатель в моем случае нормально.


Надеюсь, нормально. Ибо при использовании указателя сразу возникает вопрос времени жизни указуемого объекта. Кому принадлежит указуемый 'CFile' и кто управляет его временим жизни?
Best regards,
Андрей
shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

Post by shadow7256 »

Да действительно, нашел место, где неявно (! :х ) вызывается конструктор копирования класса А. Ну и закопали...
User avatar
AndreyT
Уже с Приветом
Posts: 3000
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

shadow7256 wrote:Да действительно, нашел место, где неявно (! :х ) вызывается конструктор копирования класса А. Ну и закопали...


Ты всегда можешь явно объявить private конструктор копирования для класса 'A' (определять не надо), и компилятор тебе радостно выложит все места, где этот конструктор вызвается, независимо от глубины закопки :umnik1:
Best regards,
Андрей
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

AndreyT wrote:Ни в коем случае. Присваивание в такой ситуации выполняется только оператором присваивания. Инициализация - только конструктором. Деление совершенно четкое и однозначное.


неверно.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
adb
Уже с Приветом
Posts: 9275
Joined: 14 Dec 2001 10:01
Location: Российская Федерация

Post by adb »

A. Fig Lee wrote:
AndreyT wrote:Ни в коем случае. Присваивание в такой ситуации выполняется только оператором присваивания. Инициализация - только конструктором. Деление совершенно четкое и однозначное.

неверно.


Покажите пункт стандарта, где сказанно про возможность замены. Или приведите пример и компилятор.
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

adb wrote:
A. Fig Lee wrote:
AndreyT wrote:Ни в коем случае. Присваивание в такой ситуации выполняется только оператором присваивания. Инициализация - только конструктором. Деление совершенно четкое и однозначное.

неверно.


Покажите пункт стандарта, где сказанно про возможность замены. Или приведите пример и компилятор.

В стандарте - не сказано. Ето оптимизация.
VC++ - делает. Уверен, что и все остальные.
Например, если функция виртуальная, а обьект не на хипе, вызов будет тоже не через виртуальную таблицу. Оптимизация-с..
Верить нельзя никому - даже себе. Мне - можно!
User avatar
AndreyT
Уже с Приветом
Posts: 3000
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

A. Fig Lee wrote:
adb wrote:
A. Fig Lee wrote:
AndreyT wrote:Ни в коем случае. Присваивание в такой ситуации выполняется только оператором присваивания. Инициализация - только конструктором. Деление совершенно четкое и однозначное.

неверно.


Покажите пункт стандарта, где сказанно про возможность замены. Или приведите пример и компилятор.

В стандарте - не сказано. Ето оптимизация.
VC++ - делает.


Нет. VC ничего подобного не делает. Если тебе показалось, что он это где-то делал - приведи конкретный пример, мы объясним тебе твою ошибку.

Также не ясно, каким боком это может относиться к "оптимизации"...

Уверен, что и все остальные.


Ни в коем случае.

Например, если функция виртуальная, а обьект не на хипе, вызов будет тоже не через виртуальную таблицу. Оптимизация-с..


Во-первых, опять неверно. Способ вызова зависит не от того, "на хипе" объект или не "на хипе", а от того, осуществляется ли вызов через указатель/ссылку на объект или через явный экземпляр объекта. А также от ряда других факторов (квалифицированные вызовы, вызовы в конструкторах/деструкторах и т.п).

Во-вторых, спецификация языка С++ вообще не содержит понятия "виртуальной таблицы". Правила вызова виртуальных методов определяются через понятие динамического типа значения объектного выражения. Если на стадии компиляции динамичиский тип объекта известен, то вызов виртуальной функции может быть выполнен точно так же, как вызов обычной функции (без участия каких-либо "виртуальных таблиц"). И это не имеет никакого отношения ни к какой "оптимизации". Этот банальная разумная кодогенерация.
Best regards,
Андрей

Return to “Вопросы и новости IT”