在Scott Meyers的 Effective C ++ 的第6页,定义了“复制构造函数”一词。我一直在使用Schiltdt的书作为我的参考,我找不到复制构造函数。我明白这个想法,但这是c ++的标准部分吗?当按类传递一个类时会调用这样的构造函数吗?
答案 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 ++编译器提供默认的复制构造函数,如果我们没有在类中显式定义它,我们也会为这个类编写复制构造函数,原因如下。
要制作深层副本,您必须编写一个复制构造函数并重载赋值运算符,否则副本将指向原始副本,并带来灾难性后果。
复制构造函数语法如下所示:
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表格):
答案 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;
}