当将数组对象作为函数参数传递时,为什么复制构造函数会调用自身?

时间:2019-05-22 13:03:06

标签: c++

一个简单的程序,什么也没做,但是任何人都可以解释为什么当在函数参数中传递对象数组时,复制构造函数没有调用自身吗?仅初始化一个对象时,效果很好

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;
}

1 个答案:

答案 0 :(得分:0)

它只是传递指向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版本)。