Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
0 / 0 / 4
Регистрация: 09.04.2016
Сообщений: 128

Конструктор копирования в С++

25.06.2018, 22:00. Показов 2729. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Такой вопрос, работает ли такой синтаксис, если я передаю указатель на объект, а не объект?

C++
1
2
3
4
имяКласса (const имяКласса & object)
{
    //код конструктора копирования
}
не лучше ли сделать так?:
C++
1
2
3
4
имяКласса (имяКласса * object)
{
    //код конструктора копирования
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.06.2018, 22:00
Ответы с готовыми решениями:

Не могу сделать чтобы класс содержал основной конструктор и конструктор копирования
Разработать класс ThreeAngle для работы с плоскими треугольниками. В качестве членов-данных задаются длины трех сторон треугольника. Класс...

Конструктор класса, конструктор копирования запускается не тот который нужен
Есть такой конструктор: Neuron::Neuron(int iType_activation_funk) { this->iType_act = iType_activation_funk; switch...

Не могу правильно сделать конструктор и конструктор копирования и принадлежность точки с заданными координатами треугольнику
#include "stdafx.h" #include <iostream> #include <conio.h> #include <windows.h> #include <math.h> #include <algorithm> using...

22
192 / 128 / 52
Регистрация: 19.01.2010
Сообщений: 518
25.06.2018, 22:33
Цитата Сообщение от IlushaMax Посмотреть сообщение
имяКласса (const имяКласса & object)
он так и пишется. И это не указатель на объект, а константная ссылка
Цитата Сообщение от IlushaMax Посмотреть сообщение
не лучше ли сделать так?:
а чем это лучше? а вдруг nullptr подпихнут?
0
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
26.06.2018, 00:09
Цитата Сообщение от IlushaMax Посмотреть сообщение
не лучше ли сделать так?
А чем должно быть лучше?

Добавлено через 36 секунд
Цитата Сообщение от Selot Посмотреть сообщение
а вдруг nullptr подпихнут?
Nullptr могут и через ссылку подпихнуть.
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
26.06.2018, 00:17
Цитата Сообщение от shmkv Посмотреть сообщение
Nullptr могут и через ссылку подпихнуть
Нет, не могут.
0
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
26.06.2018, 01:12
Цитата Сообщение от New man Посмотреть сообщение
Нет, не могут.
C++
1
2
T *p = nullptr;
f(*p);
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.06.2018, 01:35
Цитата Сообщение от New man Посмотреть сообщение
Нет, не могут.
C++
1
2
3
4
A* pa = new A();
A& ra = *pa;
delete pa;//bingo
A a(ra);
IlushaMax, вопрос
Цитата Сообщение от IlushaMax Посмотреть сообщение
не лучше ли сделать так?:
нужно объяснить компилятору. Конструктор копирования ищется по сигнатуре и нужен при различных случаях, таких как
передача/возврат, например.
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
26.06.2018, 01:47
IGPIGP, только вот в твоём коде &ra!=nullptr

А вот
A& ref = *((A)nullptr); уже UB и сегфолт зачастую. А значит, в мало-мальско сносном коде ссылка точно никогда не будет указывать на nullptr, о чём писали выше.

Добавлено через 3 минуты
shmkv, твой код — UB, такого не должно быть.

А вот то, что в указателе может быть nullptr, стандартом допускается.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
26.06.2018, 03:56
Цитата Сообщение от shmkv Посмотреть сообщение
C++
1
2
T *p = nullptr;
f(*p);
Никакой null в конструктор не пропихнули. Ошибка появляется ДО его пропихивания.
во второй строчке вообще два разных действия.
Сначала происходит UB когда ломается с UB вычисление выражения в скобках, потом идёт собственно вызов, который не ответственнен за поломку.

Не по теме:

потом идёт - некорректно так говорить, но смысл ясен


всё равно что обвинить автора функции foo в том, что не предусмотрел ошибку с отрицательным значением аргумента
C++
1
foo( sqrt(-1) );
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.06.2018, 09:39
Цитата Сообщение от New man Посмотреть сообщение
IGPIGP, только вот в твоём коде &ra!=nullptr
Конечно. Только nullptr переданный с указателем это меньшее из зол. Такой указатель нельзя разыменовывать, но можно проверить на равенство nullptr. А вот указатель инициализированный чем попало или содержащий невалидный адрес проверить, мягко говоря, также просто как и дохлую ссылку. Моя реплика была не о nullptr, а о том, что безопасность ссылки по сравнению с указателем несколько преувиличена. И главное, не имеет отношения к теме о конструкторах копирования.
Кроме всего. Если вы так уж хотите буквальных и не требующих размышлений ответов то извольте:
C++
1
2
3
4
5
A* pa = new A();
A& ra = *pa;
//delete pa;//bingo
pa=nullptr;
A a(ra);
Это не значит, что ссылка указывает на nullptr. Но и указатель который содержит значение nullptr тоже неизвестно куда указывает. Главное, что адрес не валиден.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.06.2018, 10:23
функция, которая по смыслу должна принимать
только живой валидный объект не должна допускать
даже намёка на то, что объект может быть не валиден.
такая функция принимает по ссылке,
закладываясь, что ссылка априори валидная.

ситуация, когда функции, которая ожидает валидный обьект,
а ей скормили инвалида - программная ошибка в логике.
в этом случае нужно дебажить/править код,
а не изобретать костыли аля проверки указателя на нуль.

зы: ошибок с протухшими указателями больше,
чем с протухшими ссылками
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.06.2018, 12:09
Цитата Сообщение от hoggy Посмотреть сообщение
зы: ошибок с протухшими указателями больше,
чем с протухшими ссылками
Кто же спорит? Однако, сигнатура конструктора копии (не перемещающего, а то совсем утонем), это контракт вшитый в язык. То что, в этом была какая-то логика (надеть подгузники на взрослых мужиков и получить невозможность отложенной инициализации с последствиями в виде невозможности создания массивов ссылое например) это бесспорно. Но вопрос топика:
Цитата Сообщение от IlushaMax Посмотреть сообщение
не лучше ли сделать так?:
И ответ - не лучше, потому, что это просто, не будет работать как конструктор копии. Может я не понял вопрос?
0
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
26.06.2018, 12:18
Цитата Сообщение от New man Посмотреть сообщение
shmkv, твой код — UB, такого не должно быть.
А разыменование нулевого указателя в коде функции не UB? Или будем обсуждать какое UB более UB? На практике мне приходится разбирать больше число дампов как с невалидными указателями, так и с ссылками. Но ссылки все же предпочтительнее т. к. могут защитить от неправильного использования. Но от ошибок в логике никакой защиты они не дают.

Добавлено через 2 минуты
Цитата Сообщение от New man Посмотреть сообщение
А значит, в мало-мальско сносном коде ссылка точно никогда не будет указывать на nullptr
Весьма громкое заявление.

Добавлено через 3 минуты
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Сначала происходит UB когда ломается с UB вычисление выражения в скобках, потом идёт собственно вызов, который не ответственнен за поломку.
Даже объяснять лениво, да и, видимо, бесполезно. IGPIGP вижу попытался.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.06.2018, 12:18
Цитата Сообщение от shmkv Посмотреть сообщение
Весьма громкое заявление.
норма жизни
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
26.06.2018, 12:28
Прелесть конструктора копирования в том, что он используется в стандартной библиотеке для работы с контейнерами. Также с ним работают некоторые оптимизации компилятора.

Определить конструктор для указателя можно, но возможно, стоит просто разыменовывать указатель перед передачей в конструктор.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.06.2018, 12:40
Цитата Сообщение от Mirmik Посмотреть сообщение
Прелесть конструктора копирования в том, что он используется в стандартной библиотеке для работы с контейнерами.
Он вообще говоря в функциях используется, а так же при явном вызове копирования. В том числе при инициализации присваиванием. Прелестей у него много.
А вот у константной ссылки есть прелесть которая позволяет передавать объекты на которые нельзя взять адрес. В этом их преимущество и... ржавый и гнутый гвоздь:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
using namespace std;
string where = "none";
struct IntAble
    {
        int a;
 
        IntAble(int a_=0):a(a_){
            cout<<"greatings from: "<<where<<" I am ctor and I can throw!"<<endl;       
        where = "none";
        }
 
    };
 
void foo(const IntAble & a){    
cout<<a.a<<endl;
}
void foo(const IntAble * a){    
cout<<a->a<<endl;
}
int main(int argc, char* argv[])
{
    where = "foo &";
foo(123);
 
where = "main";
IntAble a=234;//тут можно поймать
    where = "foo *";
foo(&a);//а тут его не будет
cout<<endl;
system("pause");
return 0;
}
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
26.06.2018, 12:49
Хорошее замечание. Конструктор копирования может работать с временными объектами без черной магии, в отличи от конструктора с параметром-указателем.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.06.2018, 13:21
Цитата Сообщение от Mirmik Посмотреть сообщение
Конструктор копирования может работать с временными объектами без черной магии
А указатели с ними просто не работают. Вне зависимости от магии неявных преобразований, вызываемой ссылками на приведения. Но я имел ввиду не это. Я имел ввиду тот простой факт, что передача указателя гарантирует отсутствие исключения на вызываемой стороне, вызванного конструированием (бошенного из конструктора).
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
26.06.2018, 14:20
Лучший ответ Сообщение было отмечено Kuzia domovenok как решение

Решение

Цитата Сообщение от shmkv Посмотреть сообщение
T *p = nullptr;
f(*p);//undefined behavior
There shall be no references to references, no arrays of references, and no pointers to references. The declaration of a reference shall contain an initializer (11.6.3) except when the declaration contains an explicit extern specifier (10.1.1), is a class member (12.2) declaration within a class definition, or is the declaration of a parameter or a return type (11.3.5); see 6.1. A reference shall be initialized to refer to a valid object or function. [ Note: In particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior. As described in 12.2.4, a reference cannot be bound directly to a bit-field. — end note ]
Программы, которые не well-defined обсуждать нет смысла.
Цитата Сообщение от IlushaMax Посмотреть сообщение
не лучше ли сделать так?
Это уже не будет являться конструктором копирования.
Конструктор копирования - это конструктор у которого первый параметр lvalue-ссылка на объект этого же класса, а остальные параметры заданы по-умолчанию, либо отсутствуют. То есть для типа Some, конструктор копирования может выглядеть как-то так так:
C++
1
2
3
4
Some(Some &);//Один параметр
Some(Some const &);//Один параметр
Some(Some const &, int = 10, double = 33.9);//Несколько параметров, но все кроме первого заданы по-умолчанию.
//...
2
0 / 0 / 4
Регистрация: 09.04.2016
Сообщений: 128
26.06.2018, 15:42  [ТС]
То-есть если у меня есть класс Class и конструктор
C++
1
2
3
4
имяКласса (const имяКласса & object)
{
    //код конструктора копирования
}
Class class1;
Class *class2;
Я могу вызвать Class(class1); и Class(class2); и получу одно и тоже?
Извиняюсь, уже понял, просто мой первый ооп язык - java, ещё не привык
Там он скорее такой
C++
1
2
3
4
имяКласса (имяКласса * object)
{
    //код конструктора копирования
}
0
1378 / 522 / 72
Регистрация: 21.07.2015
Сообщений: 1,308
26.06.2018, 15:53
Цитата Сообщение от IlushaMax Посмотреть сообщение
и получу одно и тоже?
Второй вариант вообще не скомпилируется.

Добавлено через 37 секунд
Цитата Сообщение от Croessmah Посмотреть сообщение
Программы, которые не well-defined обсуждать нет смысла.
Согласен, но с этого и началось обсуждение.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.06.2018, 15:53
Помогаю со студенческими работами здесь

Конструктор инициализации, конструктор копирования, деструктор
Я сделал почти задание по перегрузке операторов. Осталось одно, тоесть три: конструктор инициализации, конструктор копирования, деструктор....

Создать класс "Вектор" и реализовать конструктор по умолчанию, конструктор копирования и деструктор
Всем доброго времени суток! нужна ваша помощь! нужно создать класс вектор и реализовать конструктор по умолчанию, копирования и...

Конструктор копирования
Выдераю кусок кода с программы надеюсь поймете кто будет смотреть: конструктор: myclass(const myclass &amp;other) { this-&gt;size=...

Конструктор копирования
Почему экземпляры класса копируются без конструктора копий ? и к тому же получили разные адреса ? =====array2.h.cpp======= …….. ...

Конструктор копирования
Есть вопрос. Как объект одного класса передать в объект другого класса?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru