当前位置: 首页 > news >正文

C++ 面向对象 - 对象定义方法汇总

C++对象定义方法汇总

1. 栈上定义方式

1.1 调用无参构造函数的定义方式

无参构造函数有两种:

  • 默认无参构造函数
    Demo(){}
    
  • 默认值列表构造函数
    Demo():a{1},b{2}{}	// 使用初始化列表实现
    

对象定义方式

Demo d;	
Demo d1{}; 
// 以下定义方式还调用了拷贝构造函数
Demo d2 = Demo();
Demo d3 = Demo{};

🚫 注意事项:

  • 一个类只能有一个无参构造函数:无参构造函数的参数列表都为空,无法实现函数重载。
  • 不能使用对象名()调用无参构造函数
  • 可以使用类名()的方式创建对象
  • 推荐使用花括号定义对象

示例

class Demo1{
public:// 无参构造函数Demo(){cout << "无参构造函数"}
}class Demo2{
private:int a;int b;
public:// 默认值列表构造函数Demo():a{1},b{2}{cout << "默认值列表构造函数"<< endl;}
}int main()
{// 栈变量Demo1 d1;	// 调用无参构造函数Demo2 d2{};  // 调用无参构造函数Demo1 d3 = Demo1();Demo2 d4 = Demo2{};// Demo2 d3(); // 错误
}
1.2 调用有参构造函数的定义方式

有参构造函数通过不同的参数列表进行重载。一个类中可以存在多个有参构造函数。
有参构造函数也可以使用参数默认值简化重载。包括兼并无参构造函数。

有参构造函数定义:

Demo(int a, int b):a(a),b(b){}

带默认值的有参构造函数定义:

Demo(int a = 1):a(a),b(1){}

此有参构造函数兼并无参构造函数,若定义了无参构造函数则会起冲突。

对象定义方式
调用有参构造函数的对象定义通过(){}来传递参数。
主流推荐使用{}

Demo d(2);	
Demo d1{2, 3}; 
// 以下定义方式还调用了拷贝构造函数
Demo d2 = Demo(2, 3);
Demo d3 = Demo{2};

示例

#include <iostream>
using namespace std;class Demo{
private:int a;int b;
public:// 带默认值的有参构造函数,可替代无参构造函数Demo(int a = 1):a{a},b{2}{cout << "带默认值的有参构造函数"<< endl;}// 初始化列表构造函数Demo(int a, int b):a{a},b{b}{cout << "初始化列表构造函数"<< endl;}
};int main()
{// 栈变量Demo d1;	// 有参构造函数Demo d2{3};	// 有参构造函数Demo d3{3, 4};  // 初始化列表构造函数Demo d4(3, 4);  // 初始化列表构造函数Demo d5 = Demo(2);	// 有参构造函数Demo d6 = Demo{2};	// 有参构造函数Demo d7 = Demo(2,6);	// 初始化列表构造函数Demo d8 = Demo{2,6};	// 初始化列表构造函数return 0;
}
1.3 调用拷贝构造函数的定义方式

拷贝构造函数是在用同类对象来定义新对象时调用。已经规定死了它的函数名和参数列表,所以不存在重载,一个类也只有一个拷贝构造函数。
拷贝构造函数定义:

Demo(const Demo& d):a{d.a},b{d.b}{}

对象定义方式
拷贝构造函数是一种有参构造函数,遵循有参构造函数的对象定义方式。也有一种独特的定义方式:=

Demo d1;	// 要先存在一个用来拷贝的对象
Demo d2(d1);
Demo d3{d1};
Demo d4 = d1;	// 对象定义时,= 号调用的是拷贝构造函数
Demo d4 = Demo();	// 通过临时对象来定义新对象

示例

#include <iostream>
using namespace std;class Demo{
private:int a;int b;
public:// 带默认值的有参构造函数,可替代无参构造函数Demo(int a = 1):a{a},b{2}{cout << "带默认值的有参构造函数"<< endl;}// 拷贝构造函数Demo(const Demo& d):a{d.a},b{d.b}{cout << "拷贝构造函数"<< endl;}
};int main()
{// 栈变量Demo d1;	// 有参构造函数// 拷贝构造函数Demo d11(d1);Demo d12{d1};Demo d13 = d1;Demo d2 = Demo(2);	// 有参构造函数Demo d3 = Demo{2};	// 有参构造函数return 0;
}

2. 堆上定义方式

堆上定义对象主要通过堆操作符new来实现,它返回一个对象指针。

1.1 调用无参构造函数的定义方式
Demo *pd = new Demo;		// 无参构造函数Demo *pd10 = new Demo[2];	// 无参构造函数,返回对象数组Demo *pd2 = new Demo();		// 无参构造函数Demo *pd3 = new Demo{};		// 无参构造函数
1.2 调用有参构造函数的定义方式
Demo *pd4 = new Demo(1);	// 有参构造函数
Demo *pd5 = new Demo{1};	// 有参构造函数
1.3 调用拷贝构造函数的定义方式
Demo d1;
Demo *pd1 = new Demo(d1);
Demo *pd2 = new Demo{d1};

3. 总结

对象定义方式有两大类:

  • 对象名类名 对象名;
  • 类名类名()
    对象定义的三小类:
  • 无参构造:可无符号、可带(){}。变量名不能带(),类名可以带()
  • 有参构造:可通过(){}传递参数。
  • 拷贝构造:由(){}=传递同类对象参数。

对象定义是指对象第一次创建,构造函数只会在对象第一次创建的时候调用,若是已有对象使用了与对象定义相似的格式,必定不会调用构造函数。

4. 综合示例

#include <iostream>
using namespace std;class Demo{
private:int a;int b;
public:// 无参构造函数
//	Demo(){cout << "无参构造函数"}// 默认值列表构造函数Demo():a{1},b{2}{cout << "无参构造函数"<< endl;}// 有参构造函数Demo(int a):a{a},b{2}{cout << "有参构造函数"<< endl;}// 初始化列表构造函数Demo(int a, int b):a{a},b{b}{cout << "初始化列表构造函数"<< endl;}// 拷贝构造函数Demo(const Demo& d):a{d.a},b{d.b}{cout << "拷贝构造函数"<< endl;}// 赋值运算符重载Demo& operator=(const Demo& d){cout << "赋值运算符重载"<< endl;if(this == &d) return *this;a = d.a;b = d.b;return *this;}
};int main()
{// 栈变量Demo d;	// 无参构造函数Demo d1{};  // 无参构造函数Demo d2{3};	// 有参构造函数Demo d3{3, 4};  // 初始化列表构造函数Demo d4(3, 4);  // 初始化列表构造函数Demo d5 = Demo();	// 无参构造函数Demo d6 = Demo{};	// 无参构造函数Demo d7 = Demo(2);	// 有参构造函数Demo d8 = Demo{2};	// 有参构造函数Demo d9 = Demo(2,6);	// 初始化列表构造函数Demo d10 = Demo{2,6};	// 初始化列表构造函数// 堆变量Demo *pd = new Demo;		// 无参构造函数Demo *pd10 = new Demo[2];Demo *pd2 = new Demo();		// 无参构造函数Demo *pd3 = new Demo{};		// 无参构造函数Demo *pd4 = new Demo(1);	// 有参构造函数Demo *pd5 = new Demo{1};	// 有参构造函数Demo *pd6 = new Demo(1, 2);	// 初始化列表构造函数Demo *pd7 = new Demo{1, 2};	// 初始化列表构造函数// 拷贝构造函数Demo d11(d4);Demo d12{d4};Demo d13 = d3;Demo *pd8 = new Demo(d4);Demo *pd9 = new Demo{d4};// 赋值运算符重载d11 = d3;*pd9 = d4;return 0;
}
http://www.dtcms.com/a/273851.html

相关文章:

  • MySQL:分析表锁的常见问题
  • Flowable 使用遇到问题
  • Redis Sentinel哨兵集群
  • 碳中和目标下的全球产业链重构:深度解析与未来路径
  • Maui劝退:用windows直接真机调试iOS,无须和Mac配对
  • 单片机显示Unicode字符介绍
  • PDXP、UDP与HDLC协议技术解析:架构、应用与对比研究
  • SpringBoot 拦截器和过滤器的区别
  • 如何高效验证代理IP的可用性与稳定性
  • 瀚高数据库提交数据后,是否需要COMMIT(APP)
  • oracle
  • 从代码学习深度学习 - 针对序列级和词元级应用微调BERT PyTorch版
  • 线程池拒绝策略执行之后的补偿案例
  • Express + @vladmandic/face-api + mySql 实现人脸识别
  • Oracle 数据库 Dblink
  • 【项目经理】实施项目技术问题
  • 5G标准学习笔记14 - CSI--RS概述
  • Telnet远程连接实验(Cisco)
  • 包稳定的Docker 安装方式(CentOS)
  • 前端实现 MD5 加密
  • 【Linux应用】Ubuntu20.04 aarch64开发板一键安装ROS2(清华源)
  • 登录超时问题的排查方法与预防经验分享
  • 【机器学习】机器学习基础
  • 设计模式笔记_结构型_代理模式
  • GPT3/chatGPT/T5/PaLM/LLaMA/GLM主流大语言模型的原理和差异
  • 触觉反馈手套技术是迈向远程机器人系统灵巧操作的关键一步
  • 【Linux】系统引导修复
  • 【八股消消乐】浅尝Kafka性能优化
  • 服务器机柜与网络机柜各自的优势
  • 微信小程序111~120