Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1

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

16.12.2018, 22:58. Показов 1464. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Если вы увидели здесь что-то, что на приличной работе бы не пропустили по ревью, так как там С стиль, то напишите об этом. Мне интересно, что не стоит в принципе использовать. Но этот пример просто учебный. В целях понимания и пишутся все эти массивы странные и т.д.

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
#pragma once
#include <string>
 
namespace ClassesAndStructs
{
    class Person
    {
    public:
        Person(const Person& person);         // Конструктор копирования
        Person(Person&& person) noexcept;     // Конструктор перемещения
        Person(const std::string& firstName, const std::string& lastName);
        ~Person();
        void SetFirstName(const std::string& firstName);
        std::string GetFullName() const;
        const int32_t* GetData() const;
 
        const int32_t DATA_SIZE = 50;
    private:
        std::string _firstName;
        std::string _lastName;
 
        int32_t * _data;
    };
}
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "Person.h"
 
namespace ClassesAndStructs
{
    Person::Person(const std::string& firstName, const std::string& lastName)
    {
        _firstName = firstName;
        _lastName = lastName;
 
        _data = new int32_t[DATA_SIZE];
        for (int32_t i = 0; i < DATA_SIZE; ++i)
        {
            *(_data + i) = i; // Просто для примера - арифметика указателей
        }
    }
 
    Person::Person(const Person& person) // Конструктор копирования
        : _data(nullptr)
    {
        _firstName = person._firstName;
        _lastName = person._lastName;
 
        int32_t* newData = new int32_t[DATA_SIZE];
        std::copy(person._data, person._data + DATA_SIZE, newData);
        _data = newData;
    }
 
    Person::Person(Person&& person) noexcept // Конструктор перемещения
    {
        _firstName = std::move(person._firstName);
        _lastName = std::move(person._lastName);
 
        _data = person._data;
    }
 
    Person::~Person()
    {
        delete[] _data;
        _data = nullptr;
    }
 
    void Person::SetFirstName(const std::string& firstName)
    {
        _firstName = firstName;
    }
 
    std::string Person::GetFullName() const
    {
        return _firstName + " " + _lastName;
    }
 
    const int32_t* Person::GetData() const
    {
        return _data;
    }
}
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <string>
#include "Person.h"
#include <iomanip>
 
using namespace ClassesAndStructs;
 
void pause(const std::string &text);
Person copyPerson(Person& person);
Person modifyPerson(Person& person);
void display(const std::string& message, Person& person);
void display(int const *array, int arraySize);
 
int main()
{
    using namespace  std;
    cin.putback('\n');
 
    Person person1("John", "Smith");
    display("Before copying", person1);
 
    Person person2 = copyPerson(person1);
    display("After copying", person2);
 
    Person person3 = modifyPerson(person1);
    display("After modifying", person3);
    
    pause("Pause");
    return 0;
}
 
void display(const std::string& message, Person& person)
{
    std::cout << message << " " << person.GetFullName() << std::endl;
    display(person.GetData(), person.DATA_SIZE);
}
 
void display(int const *array, int arraySize)
{
    using namespace  std;
 
    cout << ": {";
    for (int i = 0; i < arraySize; ++i)
    {
        cout << setw(3) << *(array + i) << ",";
    }
    cout << '\b' << " }" << endl;
}
 
void pause(const std::string &text = "")
{
    using namespace  std;
 
    if (text.length() > 0) { cout << text << endl; }
    if (cin.fail()) { cin.clear(); }
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    cin.get();
}
 
Person copyPerson(Person& person)
{
    return Person(person);
}
 
Person modifyPerson(Person& person)
{
    person.SetFirstName("modifyPerson");
    return person;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
16.12.2018, 22:58
Ответы с готовыми решениями:

Почему не вызывается конструктор перемещения?
#include &lt;iostream&gt; #include &lt;vector&gt; class Object { public: Object() { std::cout &lt;&lt; &quot;Object()&quot; &lt;&lt; std::endl; ...

Почему не вызывается конструктор копии?
Почему не вызывается конструктор копии? class CPoint { friend std::istream &amp;operator&gt;&gt;(std::istream &amp;in, CPoint &amp;obj); ...

Почему не вызывается конструктор копирования?
...У меня в книге описаны случаи при которых вызывается конструктор копирования. Один из этих случаев: : &quot;Когда аргумент имеет...

5
112 / 91 / 31
Регистрация: 24.10.2018
Сообщений: 336
16.12.2018, 23:10
Цитата Сообщение от Casper-SC Посмотреть сообщение
Почему не вызывается конструктор перемещения?
Где ты ожидаешь его вызов?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
16.12.2018, 23:17  [ТС]
modifyPerson модифицирует person1 и вызвав конструктор копирования копирует. Так что название функции чуть не в тему. Я надеялся, что там будет при возврате вызван конструктор перемещения, но увы.

Добавлено через 28 секунд
Цитата Сообщение от krolligator Посмотреть сообщение
Где ты ожидаешь его вызов?
При возврате из copyPerson и modifyPerson

Добавлено через 38 секунд
В книге написано, что если создать конструктор перемещения, то компилятор будет использовать его, а не конструктор копирования при возврате из функции. Или я, возможно, чего-то не понял в книге.

Добавлено через 2 минуты
В качестве DATA_SIZE, похоже, нужно использовать size_t?

Добавлено через 1 минуту
И здесь тоже нужно использовать size_t вместо int32_t?
C++
1
for (int32_t i = 0; i < DATA_SIZE; ++i)
0
112 / 91 / 31
Регистрация: 24.10.2018
Сообщений: 336
16.12.2018, 23:38
Цитата Сообщение от Casper-SC Посмотреть сообщение
При возврате из copyPerson
Зачем лишний раз вызывать конструктор перемещения, если уже все на местах? person не временный объект. Объект конструируется из person1 на месте в памяти. По сути, это просто Person person2{person1};. Больше никаких лишних конструкторов не нужно.
Цитата Сообщение от Casper-SC Посмотреть сообщение
и modifyPerson
Здесь вообще нельзя, этот объект пришел извне. Почему он вдруг должен стать rvalue?
0
Эксперт .NET
 Аватар для Casper-SC
4434 / 2094 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
17.12.2018, 00:04  [ТС]
Цитата Сообщение от krolligator Посмотреть сообщение
Здесь вообще нельзя, этот объект пришел извне. Почему он вдруг должен стать rvalue?
Да, точно. Я пока не всё идеально уловил, нужно время и практика.

Добавлено через 2 минуты
Цитата Сообщение от krolligator Посмотреть сообщение
Зачем лишний раз вызывать конструктор перемещения, если уже все на местах? person не временный объект.
C++
1
2
3
4
Person copyPerson(Person& person)
{
    return Person(person);
}
Передали в функцию copyPerson по ссылке объект person, создали на стеке новый объект типа Person, в копирующий конструктор которого по ссылке был передан исходный объект person. Далее идёт возврат созданного на стеке в области видимости функции copyPerson объекта типа Person, вот во время его возврата из функции я ожидаю не вызов конструктора копирования (что происходит по факту), а вызов конструктора перемещения ибо глубинное копирование здесь излишне.
0
112 / 91 / 31
Регистрация: 24.10.2018
Сообщений: 336
17.12.2018, 00:14
Цитата Сообщение от Casper-SC Посмотреть сообщение
В качестве DATA_SIZE, похоже, нужно использовать size_t?
Можно.

Добавлено через 7 минут
Цитата Сообщение от Casper-SC Посмотреть сообщение
вот во время его возврата из функции я ожидаю не вызов конструктора копирования (что происходит по факту)
А он вызывает не во время возврата, а во время Person(person); person это не rvalue. Он обязан вызвать конструктор копирования здесь. А уже при возврате может вызвать констркутор перемещения. А может оптимизировать код так, что он, по сути, превратится, грубо, в Person person2{person1}; без вызова констркутора перемещения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.12.2018, 00:14
Помогаю со студенческими работами здесь

Почему вызывается конструктор копий по умолчанию?
Всем добрый день! Не могу понять, почему не вызывается конструктор копий. Вот, для примера, код: class TestClass { public: ...

Почему вызывается конструктор, а не создание массива?
struct KTest { KTest(int _a, double _b, long long _c) : a(_a), b(_b), c(_c) {} friend ostream&amp; operator &lt;&lt; (ostream&amp; os, KTest const&amp;...

Почему Конструктор не вызывается и не присваивает введенные значения?
Ребят, подскажите пожалуйста, почему значение в скобках не присвоились(выдает 0)? Путаюсь с помощью объявленного конструктора выполнить...

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

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


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru