Почему конструктор перемещения используется поверх конструктора копирования? - PullRequest
0 голосов
/ 14 ноября 2018

Это простая программа, которая должна обрабатывать динамический массив чисел, а затем отфильтровывать четные элементы и помещать их в новый массив, а затем выводить на экран оба массива.

Это заголовочный файл:

#pragma once


namespace filter
{
    class Array
    {
        double *arr;
        int n;

public:
    Array();
    Array(int);
    Array(const Array&);
    Array(Array&&);
    void PutIn();
    void PrintOut() const;
    Array isEven();
    Array filter(const std::function<bool(int)>&) const;
    ~Array();

};
}

Тогда это реализация функций:

#include <iostream>
#include <functional>
#include "Array.h";
using namespace filter;
using namespace std;

Array::Array() :arr(nullptr), n(0)
{ }

Array::Array(int n)
{
    this->n = n;
    arr = new double[n];
}

Array::Array(const Array &a1)
{
    n = a1.n;
    arr = new double[n];
    for (int i = 0; i < n; i++)
        arr[i] = a1.arr[i];
}

Array::Array(Array &&a1)
{
    n = a1.n;
    for (int i = 0; i < n; i++)
        arr[i] = a1.arr[i];
    a1.n = 0;
    a1.arr = nullptr;
}

void Array::PutIn()
{
    cout << "Insert elements:\n";
        for (int i = 0; i < n; i++)
            cin >> arr[i];

}
void Array::PrintOut() const
{
    cout << "\nYour array is :\n";
    for (int i = 0; i < n; i++)
        cout << arr[i] << "\t";
}

Array Array::isEven()
{
    return filter([](int x) { return x % 2; });
}
Array Array::filter(const std::function<bool(int)> &f) const
{
    int b = 0;

    for (int i = 0; i < n; i++)
        if (f(arr[i]) == 0)
            b++;

    Array temp(b);
    b = 0;
    for (int i = 0; i < n; i++)
        if (f(arr[i]) == 0)
        {
            temp.arr[b] = arr[i];
            b++;
        }
    return temp;
}

Array::~Array()
{
    delete[]arr;
    n = 0;
}

Наконец, это исходный код:

#include <iostream>
#include <functional>
#include "Array.h"
using namespace filter;
using namespace std;




int main()
{

    Array a(5);

    a.PutIn();

    Array b = a.isEven();    //WHY THIS LINE OF CODE INVOKES MOVE CONSTRUCTOR AND NOT COPY CONSTRUCTOR?

    a.PrintOut();
    b.PrintOut();

    getchar();
    getchar();

}

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

Если вы посмотрите на исходный код, обратите внимание на строку, где я оставил свой комментарий, это строка, где вызывается конструктор перемещения, но я не знаю почему. Это будет означать, что a.IsEven () является RVALUE, поскольку конструктор перемещения работает с RVALUES, верно? Может кто-нибудь объяснить мне, почему это rvalue и как правильно это понять? Любая помощь приветствуется!

1 Ответ

0 голосов
/ 14 ноября 2018

Ваше предположение, что вызов isEven вызывает ваш конструктор перемещения, на самом деле неверно. Он также не вызывает ваш конструктор копирования. Вместо этого RVO гарантирует, что возвращаемый объект создается непосредственно на вызывающем сайте, поэтому ни один из них не требуется.

Демонстрация в реальном времени (которая не устраняет никаких недостатков в вашем коде, упомянутых в комментариях).

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