什么是C ++中的复制构造函数?

时间:2010-01-30 14:35:40

标签: c++ constructor

在Scott Meyers的 Effective C ++ 的第6页,定义了“复制构造函数”一词。我一直在使用Schiltdt的书作为我的参考,我找不到复制构造函数。我明白这个想法,但这是c ++的标准部分吗?当按类传递一个类时会调用这样的构造函数吗?

7 个答案:

答案 0 :(得分:14)

是的,复制构造函数肯定是标准C ++的重要组成部分。阅读更多关于它们(和其他构造函数)here(C ++ FAQ)。

如果您有一本不教授复制构造函数的C ++书籍,请将其丢弃。这是一本糟糕的书。

答案 1 :(得分:10)

复制构造函数具有以下形式:

class example 
{
    example(const example&) 
    {
        // this is the copy constructor
    }
}

以下示例显示了调用它的位置。

void foo(example x);

int main(void)
{
    example x1; //normal ctor
    example x2 = x1; // copy ctor
    example x3(x2); // copy ctor

    foo(x1); // calls the copy ctor to copy the argument for foo

}

答案 2 :(得分:4)

请参阅维基百科上的Copy constructor

基本思想是复制构造函数通过复制现有实例来实例化新实例:

class Foo {
  public:
    Foo();                // default constructor
    Foo(const Foo& foo);  // copy constructor

  // ...
};

给定实例foo,使用

调用复制构造函数
Foo bar(foo);

Foo bar = foo;

标准模板库的容器要求对象是可复制和可分配的,因此如果要使用std::vector<YourClass>,请确保定义适当的复制构造函数和operator=如果编译器生成的默认值为没有意义。

答案 3 :(得分:2)

将在以下场景中调用复制构造函数:

  • 从现有对象创建新对象时。

    MyClass Obj1;
    MyClass Obj2 = Obj1; // Here assigning Obj1 to newly created Obj2
    

    MyClass Obj1;
    MyClass Obj2(Obj1);
    
  • 按值传递类对象时。

    void NewClass::TestFunction( MyClass inputObject_i )
    {
      // Function body
    }
    

    通过值传递的MyClass对象之上。所以MyClass的复制构造函数会调用。通过引用传递以避免复制构造函数调用。

  • 按值返回对象时

    MyClass NewClass::Get()
    {
      return ObjMyClass;
    }
    

    MyClass上面是按值返回的,因此MyClass的复制构造函数将调用。通过引用传递以避免复制构造函数调用。

答案 4 :(得分:1)

复制构造函数是C ++的重要组成部分。即使任何C ++编译器提供默认的复制构造函数,如果我们没有在类中显式定义它,我们也会为这个类编写复制构造函数,原因如下。

  1. 如果班级中有任何动态内存分配。
  2. 如果我们在类中使用指针变量。 (否则它将是一个浅的副本 哪两个对象将指向相同的内存位置。)
  3. 要制作深层副本,您必须编写一个复制构造函数并重载赋值运算符,否则副本将指向原始副本,并带来灾难性后果。

    复制构造函数语法如下所示:

    class Sample{
    
    public:
       Sample (const Sample &sample);
    
    };
    
    int main()
    {
    
       Sample s1;
       Sample s2 = s1;   // Will invoke Copy Constructor.
       Sample s3(s1);     //This will also invoke copy constructor.
    
       return 0;
    }
    

答案 5 :(得分:0)

Eli发布的C ++ FAQ链接很好,gbacon的帖子是正确的。

要明确回答问题的第二部分:是的,当您按值传递对象实例时,复制构造函数将用于在函数调用范围内创建对象的本地实例。每个对象都有一个“默认复制构造函数”(gbacon暗称这是“编译器生成的默认值”),它只是复制每个对象成员 - 例如,如果你的对象实例包含指针或引用,这可能不是你想要的。

关于(重新)学习C ++的好书 - 我几乎在二十年前首次学习它并且从那以后它已经改变了很多 - 我推荐Bruce Eckel的“Thinking in C ++”版本1和2,这里免费提供(in PDF和HTML表格):

http://www.ibiblio.org/pub/docs/books/eckel/

答案 6 :(得分:0)

复制构造函数是进行深度复制的构造函数。当类中存在指针类型变量时,您应该编写自己的复制构造函数。当代码中没有写明确的拷贝构造函数时,编译器会自动插入拷贝构造函数。复制构造函数参数的类型应该始终是引用类型,以避免由于传值类型导致的无限递归。

下面的程序解释了复制构造函数的使用

#include <iostream>
#pragma warning(disable : 4996)
using namespace std;
class SampleTest {
private:
    char* name;
    int age;
public:   
    SampleTest(char *name1, int age) {
        int l = strlen(name1);
        name = new char[l + 1];
        strcpy(this->name, name1);
        this->age = age;
    }
        SampleTest(const SampleTest& s) { //copy constructor 
            int l = strlen(s.name);
            name = new char[l + 1];
            strcpy(this->name, s.name);
            this->age = s.age;
        }
    void displayDetails() {
        cout << "Name is " << this->name << endl;
        cout << "Age is " << this->age << endl;
    }
    void changeName(char* newName) {
        int l = strlen(newName);
        name = new char[l + 1];
        strcpy(this->name, newName);
    }
};
int main() {
    SampleTest s("Test", 10);
    s.displayDetails();
    SampleTest s1(s);
    cout << "From copy constructor" << endl;
    s1.displayDetails();
    s1.changeName("Test1");
    cout << "after changing name s1:";
    s1.displayDetails();
    s.displayDetails();
    cin.get();
    return 0;
}