Почему конструктор копирования не вызывает себя, когда объект массивов передается в качестве аргумента функции?

Простая программа, которая ничего особенного не делает, но может ли кто-нибудь объяснить, почему конструктор копирования не вызывает себя, когда в аргументе функции передается массив объектов? Работает отлично, когда инициализируется только один объект

class Student{
    public:
        Student(string name_val="empty",int tg=2019,int gu=0):
            name{name_val},current_year{tg}{cout<<"Constructor is called "<<endl;}
        Student(const Student &source):
            name{source.name},current_year{source.current_year}{
            cout<<"Copy constructor  is called "<<endl;
            }
        ~Student(){cout<<"Destructor is called "<<endl;}

        void set(){
            cout<<"Input name and surname: ";getline(cin,name);
        }   
    private:
        string name;
        int current_year;
};

void input(Student s[],int n){//Should display when input function is called
    for(int i=0;i<n;i++){
        cout<<"Input data for "<<i+1<<". student\n";
        s[i].set();
    }
}

int main(){
    Student S[2];//Calls constructor
    input(S,2);//Should call copy constructor 
    return 0;
}

очень похоже: stackoverflow.com/questions/7454990/…

NathanOliver 22.05.2019 15:05

Для объявлений аргументов компилятор обрабатывает, например. Student s[] как Student* s.

Some programmer dude 22.05.2019 15:07
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
2
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Он передает только указатель на S, поэтому не копирует Student. Если вы действительно хотите передать копию массива, а не просто указатель на него (и, таким образом, оставить оригинал без изменений), вы можете обернуть его с помощью std::array следующим образом:

void input(std::array<Student, 2> s)

И в main:

std::array<Student, 2> S;//Calls constructor

Таким образом вы получаете:

Constructor is called
Constructor is called
Copy constructor  is called
Copy constructor  is called

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

template <unsigned int n>
void input(std::array<Student, n> s) {

И называя это так:

input<2>(S);

Или, если вы не возражаете против более низкой производительности, просто используйте вместо этого std::vector:

void input(std::vector<Student> s) {
    for (int i = 0; i < s.size(); i++) {
        cout << "Input data for " << i + 1 << ". student\n";
        s[i].set();
    }
}

int main() {
    std::vector<Student> S(2);//Calls constructor
    input(S);//Should call copy constructor 
    return 0;
}

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

void input(std::vector<Student> &s) {

Оригинал изменен, и вы больше не видите Copy constructor is called (это также работает с версией std::array).

В последнем фрагменте отсутствует &. std::array — это вариант, только если ваш аргумент действительно имеет фиксированный размер. Когда это не так, шаблоны не помогают. std::vector кажется, это то, что ищет ОП.

Frax 22.05.2019 16:09

@Frax спасибо за указание на ошибку. Вы правы, std::vector определенно правильный путь, я отредактировал пост, чтобы упомянуть об этом.

Blaze 22.05.2019 16:12

@Блэйз, спасибо! Наконец, я думаю, понял суть, практически я мог бы создать имя набора функций, которое будет копировать один объект, а затем создавать другую функцию с массивом объектов. Таким образом, в цикле for каждый объект получит свою собственную копию. Я прав ?

Finixzz 22.05.2019 20:36

@Finixzz, если я правильно понимаю, вы хотите передать указатель на массив функции, которая затем вызывает сеттер для объектов в массиве? Конечно, это сработает.

Blaze 23.05.2019 08:10

Другие вопросы по теме