拷贝构造函数
程序员文章站
2022-07-10 08:51:44
一、概述一个构造函数的参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数。class Foo{public:Foo();//默认构造函数Foo(const Foo&);//拷贝构造函数}合成拷贝构造函数如果我们没用我i类定义拷贝构造函数,编译器会为我们定义一个。与合成默认构造函数不同,即使我们定义了其他构造函数,编译器也会为我们合成一个拷贝构造函数。拷贝的成员合成的拷贝构造函数会将参数的成员逐个拷贝到正在创建的对象中。编译器从给定对象中依次将...
一、概述
一个构造函数的参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数。
class Foo
{
public:
Foo();//默认构造函数
Foo(const Foo&);//拷贝构造函数
}
合成拷贝构造函数
如果我们没有为类定义拷贝构造函数,编译器会为我们定义一个。与合成默认构造函数不同,即使我们定义了其他构造函数,编译器也会为我们合成一个拷贝构造函数。
拷贝的成员
合成的拷贝构造函数会将参数的成员逐个拷贝到正在创建的对象中。
编译器从给定对象中依次将每个非static成员拷贝到正在创建的对象中。
拷贝的成员的类型
每个成员的类型决定了它如何拷贝:对类类型成员,会使用其拷贝构造函数来拷贝。
内置类型的成员则直接拷贝。
合成拷贝构造函数会逐元素地拷贝一个数组类型成员。如果数组元素是类类型,则使用元素的拷贝构造函数来进行拷贝。
calss Sales_data
{
public:
//与合成的拷贝构造函数等价的拷贝构造函数的声明
Sales_data(const Sales_data&);
private:
std::string bookName;
int m_a = 0;
double m_b = 0.0;
}
Sales_data::Sales_data(const Sales_data &orig):
bookName(orig.bookName);//类成员,使用类的拷贝构造函数
m_a(orig.m_a);//拷贝orig.m_a
m_b(orig.m_b);//拷贝orig.m_b
{}//空函数体
现在我们可以完全理解初始化和拷贝初始化直之间的差异了
string book(10,'.');//直接初始化
string book2(book);//直接初始化
string big_book = book;//拷贝初始化
string null_book = "99";//拷贝初始化
string read_book = string(2,'9');//拷贝初始化
拷贝初始化通常使用拷贝构造函数完成。但是一个类有一个移动构造函数,则拷贝初始有时会使用移动构造函数,而非拷贝构造函数来完成。
拷贝构造函数不仅在我们用=定义变量时会发生,在下列清空也会发生
- 经一个对象作为实参传递给一个非引用类型的形参
- 从一个返回类型为非引用类型的函数返回一个对象
- 用花括号列表初始化一个数组中的元素或一个聚合类中的成员
参数和返回值
为什么拷贝构造函数的参数一定要是引用类型
在函数调用的过程中,具有非引用类型的参数要进行拷贝初始化。类似的,当一个函数具有非引用的返回类型时,返回值会被用来初始化调用结果。
拷贝构造函数被用来初始化非引用类型参数,这一特性解释了为什么拷贝构造函数的参数必须是引用类型。如果其参数不是引用类型,则调用永远也不会成功------为了调用拷贝构造函数,我们必须拷贝它的实参,但为了拷贝实参,我们有需要调用拷贝构造函数,如此无限循环。
编译器可以绕过拷贝构造函数
string book = "99"//拷贝初始化
string yellow_book("199");//编译器略过了拷贝构造函数
总结
- 拷贝构造函数,bai是一种特du殊的构造函数,zhi它由编译器调用 来完成一些dao基于同一类的其他zhuan对象的构建及shu初始化。其唯一的参数(对象的引用)是不可变的(const类型)。
- 对象在创建时使用其他的对象初始化被调用
- 对象作为函数的参数进行值传递时被调用
本文地址:https://blog.csdn.net/qq_39742528/article/details/110480408