C++继承中的对象构造与析构和赋值重载详解

 更新时间:2022年03月04日 17:09:09   作者:code-016  
这篇文章主要为大家详细介绍了C++继承中的对象构造与析构和赋值重载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

一、构造/析构顺序及继承性

class A
{
private:
	int _a;
public:
	A(int a = 0): _a(a)
	{
		cout << "A()" << this << endl;
	}
	~A()
	{
		cout << "~A()"<< this <<endl;
	}
};

class B : public A
{
private:
	int _b;
public:
	B(int b): _b(b), A()
	{
		cout << "B()" << this << endl;
	}
	~B()
	{
		cout << "~B()"<< this <<endl;
	}
};

在这里插入图片描述

结论:

1.构造顺序:先构造基类,后构造派生类

2.析构顺序:先析构派生类,后析构基类

二、拷贝构造的继承性

class A
{
private:
	int _a;
public:
	A(int a = 0): _a(a)
	{
		cout << "A()" << this << endl;
	}
	A(const A& src): _a(src._a)
	{
		cout << "A(const A& src)"<< this << endl;
	}
	~A()
	{
		cout << "~A()"<< this <<endl;
	}
};

class B : public A
{
private:
	int _b;
public:
	B(int b): _b(b), A()
	{
		cout << "B()" << this << endl;
	}
	B(const B& src): _b(src._b)
	{
		cout << "B(const B& src)" << this << endl;
	}
	~B()
	{
		cout << "~B()"<< this <<endl;
	}
};

在这里插入图片描述

结论:

1.先调用基类缺省的构造函数,后调用派生类的拷贝构造函数

2.若派生类没有缺省构造函数A(),就会报错

疑惑:如何去调用基类的拷贝构造而不是缺省构造

#include<iostream>
using namespace std;

class A
{
private:
	int _a;
public:
	A(int a = 0) : _a(a)
	{
		cout << "A()" << this << endl;
	}
	A(const A& src) : _a(src._a)
	{
		cout << "A(const A& src)" << this << endl;
	}
	~A()
	{
		cout << "~A()" << this << endl;
	}
};

class B : public A
{
private:
	int _b;
public:
	B(int b) : _b(b), A()
	{
		cout << "B()" << this << endl;
	}
	B(const B& src) : _b(src._b), A(src)	//发生赋值兼容规则(切片)
	{
		cout << "B(const B& src)" << this << endl;
	}
	~B()
	{
		cout << "~B()" << this << endl;
	}
};
int main()
{
	B b(10);
	B b1(b);
	return 0;
}

在这里插入图片描述

结果:

将B类型src传递给A类型的A(const A& src)拷贝构造函数,发生了赋值兼容规则(切片现象)

三、赋值重载不具有继承性

#include<iostream>
using namespace std;

class A
{
private:
	int _a;
public:
	A(int a = 0) : _a(a)
	{
		cout << "A()" << this << endl;
	}
	A(const A& src) : _a(src._a)
	{
		cout << "A(const A& src)" << this << endl;
	}
	A& operator=(const A& src)
	{
		if(this != &src)
		{
			_a = src._a;
			cout << "A& operator=(const A& src)" << endl;
		}
	}
	~A()
	{
		cout << "~A()" << this << endl;
	}
};

class B : public A
{
private:
	int _b;
public:
	B(int b) : _b(b), A()
	{
		cout << "B()" << this << endl;
	}
	B(const B& src) : _b(src._b), A(src)	//发生赋值兼容规则(切片)
	{
		cout << "B(const B& src)" << this << endl;
	}
	B& operator=(const B& src)
	{
		if(this != &src)
		{
			_b = src._b;
			cout << "B& operator=(const B& src)" <<  endl;
		}
	}
	~B()
	{
		cout << "~B()" << this << endl;
	}
};
int main()
{
	B b1(10);
	B b2(20);
	b1 = b2;
	return 0;
}

在这里插入图片描述

结论:默认情况下仅仅调用了派生类的对象的赋值重载,并未调用基类的赋值重载。

解决方案:

#include<iostream>
using namespace std;

class A
{
private:
	int _a;
public:
	A(int a = 0) : _a(a)
	{
		cout << "A()" << this << endl;
	}
	A(const A& src) : _a(src._a)
	{
		cout << "A(const A& src)" << this << endl;
	}
	A& operator=(const A& src)
	{
		if(this != &src)
		{
			_a = src._a;
			cout << "A& operator=(const A& src)" << endl;
		}
	}
	~A()
	{
		cout << "~A()" << this << endl;
	}
};

class B : public A
{
private:
	int _b;
public:
	B(int b) : _b(b), A()
	{
		cout << "B()" << this << endl;
	}
	B(const B& src) : _b(src._b), A(src)	//发生赋值兼容规则(切片)
	{
		cout << "B(const B& src)" << this << endl;
	}
	B& operator=(const B& src)
	{
		if(this != &src)
		{
			*(A*)this = src;	//将调用基类赋值重载
			_b = src._b;
			cout << "B& operator=(const B& src)" <<  endl;
		}
	}
	~B()
	{
		cout << "~B()" << this << endl;
	}
};
int main()
{
	B b1(10);
	B b2(20);
	b1 = b2;
	return 0;
}

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!     

相关文章

  • Visual Studio Community 2022(VS2022)安装图文方法

    Visual Studio Community 2022(VS2022)安装图文方法

    这篇文章主要介绍了Visual Studio Community 2022(VS2022)安装方法,本文分步骤通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • C语言报错Use of Uninitialized Variable的原因及解决方案

    C语言报错Use of Uninitialized Variable的原因及解决方案

    Use of Uninitialized Variable是C语言中常见且危险的错误之一,它通常在程序试图使用一个未初始化的变量时发生,本文将详细介绍Use of Uninitialized Variable的产生原因,提供多种解决方案,并通过实例代码演示如何有效避免和解决此类错误,需要的朋友可以参考下
    2024-06-06
  • 使用DeepSeek API 结合VSCode提升开发效率

    使用DeepSeek API 结合VSCode提升开发效率

    这篇文章主要介绍了DeepSeek API与Visual Studio Code (VSCode)结合使用,以提升软件开发效率,具有一定的参考价值,感兴趣的可以了解一下
    2025-01-01
  • 关于C++STL string类的介绍及模拟实现

    关于C++STL string类的介绍及模拟实现

    这篇文章主要介绍了关于C++STL string类的介绍及模拟实现的相关资料,需要的朋友可以参考下面具体的文章内容
    2021-09-09
  • epoll多路复用的一个实例程序(C实现)

    epoll多路复用的一个实例程序(C实现)

    这篇文章主要为大家详细介绍了epoll多路复用的一个实例程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++实现打印虚函数表的地址

    C++实现打印虚函数表的地址

    对于存在虚函数的类,如何打印虚函数表的地址,并利用这个虚函数表的地址来执行该类中的虚函数呢,下面小编就来和大家一起简单聊聊吧
    2023-07-07
  • 深入理解C/C++中的写时拷贝

    深入理解C/C++中的写时拷贝

    这篇文章主要给大家介绍了C/C++中写时拷贝的相关资料,所谓写时拷贝也就是拖延版的深拷贝,下面文章中介绍的非常清楚,需要的朋友可以参考学习,下面来一起看看吧。
    2017-03-03
  • QT实战之实现图片浏览系统

    QT实战之实现图片浏览系统

    这篇文章主要介绍了如何利用QT编写一个图片浏览系统,可以支持自动播放,左右拖动切换,点击列表切换,点击按钮切换等功能,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-04-04
  • 浅析多维数组的下标重载

    浅析多维数组的下标重载

    贴一下实现基本功能的代码吧,像越界检测,及其他功能就没写了,只要体现了思路,其他的功能好加
    2013-09-09
  • C++开发:为什么多线程读写shared_ptr要加锁的详细介绍

    C++开发:为什么多线程读写shared_ptr要加锁的详细介绍

    本篇文章介绍了,在C++中为什么多线程读写shared_ptr要加锁的详细说明。需要的朋友参考下
    2013-04-04

最新评论