C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)

1.构造函数:

>构造函数是一个特殊的、与类同名的成员函数,用于给每一个成员设置适当的初始值。

  1. >构造函数不能有返回值,函数名与类名同样。
  2. >缺省构造函数时,系统将自己主动调用该缺省构造函数初始化对象,缺省构造函数会将全部数据成员都初始化为零或       空。缺省构造函数是不带參数的构造函数。
  3. >创建一个对象时,系统自己主动调用构造函数。

构造函数的特点:

1.构造函数能够重载,传入什么实參决定调用不同版本号的构造函数。

2.构造函数不能声明为const 、也不能声明为virtual;(析构函数能够)

3.一个类假设自己定义了一个构造函数,编译器就不会生成默认构造函数。

4.仅仅有构造函数才有类似初始化列表的形式来初始化成员变量(特别是const成员变量仅仅能在初始化列表中初始化)

样例:

#include <iostream>
#include <new>

class Person
{
public:
	Person();//默认的构造函数
	Person(int n, const string &str);//构造函数的重载
private:
	int age;
	string *name;
};

2.拷贝构造

先介绍一下深拷贝浅拷贝

>浅拷贝: 指的是在对象复制时,仅仅对对象中的数据成员进行简单的赋值;默认拷贝构造函数运行的也是浅拷贝。
       大多情况下“浅拷贝”已经能非常好地工作了,可是一旦对象存在了动态成员,那么浅拷贝就会出问题了。

>深拷贝:当类的成员变量有指针类型时,拷贝对象时应该为指针变量又一次分配好空间,避免浅拷贝中仅仅拷贝指针的
   值,使得两个指针指向同一块内存空间。

浅拷贝缺陷样例:

#include <iostream>
#include <new>

using namespace std;

class Person
{
public:
	Person();
	Person(int n, const string &str);//构造函数重载
	~Person();
private:
	int age;
	string *name;
};

Person::Person():age(0), name(NULL)//构造函数初始化列表,定义时不必写!
{
	cout << "Default Person" << endl;
}

Person::Person(int n, const string &str):age(n), name(new string(str))
{
	cout << "Init Person" << endl;
}

Person::~Person()
{
	if(name)
	{
		cout << "~Person " << "name: " << *name << " age: " << age << endl;
	}
	delete name;
}

int main()
{
	Person p1(10, string("SCOTT"));
	Person p2 = p1;

	return 0;
}

执行结果:

Init Person

~Person name: SCOTT age: 10

Segmentation fault (core dumped)

程序崩溃原因:

p2由p1初始化而得到,因为我们没有自己定义拷贝构造函数,所以调用的是默认的拷贝构造函数,属于浅拷贝,仅仅对name的值进行了拷贝;p1与p2中的name指针指向同一个new空间,最后调用析构函数时,会造成两次delete而出现段错误。

例如以下图所看到的:

解决方法:自己定义拷贝构造函数! 达到深拷贝的效果

深拷贝样例:

#include <iostream>
#include <new>

using namespace std;

class Person
{
public:
	Person();
	Person(int n, const string &str);
	Person(const Person &n);
	~Person();
private:
	int age;
	string *name;
};

Person::Person():age(0), name(NULL)
{
	cout << "Default Person" << endl;
}

Person::Person(int n, const string &str):age(n), name(new string(str))
{
	cout << "Init Person" << endl;
}
//自己定义拷贝构造函数
Person::Person(const Person &n)
{
	if(n.name)
	{
		name = new string(*n.name);
		age = n.age;
	}
}

Person::~Person()
{
	if(name)
	{
		cout << "~Person " << "name: " << *name << " age: " << age << endl;
	}
	delete name;
}

int main()
{
	Person p1(10, string("SCOTT"));
	Person p2 = p1;

	return 0;
}

执行结果:

Init Person

~Person name: SCOTT age: 10

~Person name: SCOTT age: 10

没有出现段错误,由此可见,上述解决方式可行。

C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)

时间: 2024-10-28 16:33:03

C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)的相关文章

[terry笔记]11gR2_DataGuard搭建_拷贝数据文件

11gR2搭建dataguard环境: 自己做的实验,后续按照rman模式搭建.主备切换.模式调整等实验会陆续发上来. primary: OS:oel 6.4 database:11.2.0.4.0 192.168.100.131 hostname=node4 ORACLE_SID=good ORACLE_HOME=/u01/product/11.2.0 db_unique_name=good standby: OS:oel 6.4 database:11.2.0.4.0 192.168.100

C++ Primer笔记1_转义字符_标准库类型string_标准库类型vector

1.转义字符 一般有两种方式: \x后紧跟1个或多个十六进制数字.或\后紧跟1.2.3个八进制数字,当中数字部分是字符相应的数值. #include <iostream> using namespace std; int main() { bool b = 10; bool b1 = true; bool b2 = false; cout << b << endl; cout << b1 << endl; cout << b2 <

拷贝构造函数(二)——深拷贝与浅拷贝

拷贝构造函数(一)--哲学三连:http://www.cnblogs.com/tenjl-exv/p/8017814.html 拷贝构造函数(二)--深拷贝与浅拷贝:http://www.cnblogs.com/tenjl-exv/p/8017909.html 拷贝构造函数(三)--重载赋值运算符:http://www.cnblogs.com/tenjl-exv/p/8017983.html

C++文件头,命名空间,new和delete,内联函数,引用,函数重载,构造函数和析构函数,深拷贝和浅拷贝,explict,this指针

 目  录 1       开始学习C++.............................................................................................................. 4 1.1       C++的头文件.................................................................................................

C++:派生类的默认构造函数和拷贝构造函数调用基类构造函数的机制(含程序验证)

1.如果基类定义了不带参数的默认构造函数,则编译器为派生类自动生成的默认构造函数会调用基类的默认构造函数. 2.如果基类定义了拷贝构造函数,则编译器为派生类自动生成的拷贝构造函数同样会调用基类的拷贝构造函数. 3.如果基类定义了带参数的构造函数,派生类没有定义任何带参数的构造函数,则不能直接调用基类的带参构造函数,程序编译不通过. 代码如下: #include<iostream> using namespace std; //基类Game,定义了两个构造函数和一个拷贝构造函数 class Ga

C++ 构造函数_拷贝构造函数

拷贝构造函数 系统自动生成的函数: 普通构造函数 拷贝构造函数 如果自己定义了普通构造函数,系统不会再自动生成普通构造函数: 如果自己定义了拷贝构造函数,系统不会再自动生成拷贝构造函数. ***如果没有自定义的拷贝构造函数则系统自动生成一个默认的拷贝构造函数. ***当采用直接初始化或者复制初始化实例对象时,系统自动调用拷贝构造函数. 拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象.拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创

C++:复数类构造函数、拷贝构造、运算符重载、析构函数

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; class Complex { public:     void Set(double real, double image)     {         _real = real;         _image = image;     }     //构造函数      Complex(double real = 1, double image

C++【面试题】:类实现万年历(日期计算器),(含构造函数、拷贝构造、运算符重载、析构函数)

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<stdlib.h> using namespace std; class Date { public:     Date(int year=0, int month=0, int day=0)     :_year(year)     , _month(month)     , _day(day)     {         cout << &qu

C++构造函数实例——拷贝构造,赋值

#define _CRT_SECURE_NO_WARNINGS //windows系统 #include <iostream> #include <cstdlib> #include <cstring> using namespace std; class student { private: char *name; int age; public: student(const char *n = "no name", int a = 0) { na