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

【C++学习】对象特性--构造函数

一、类的封装

访问权限:
公共权限public :类的内外都可以使用
私有权限private : 仅类内可以访问,继承后不可访问
保护权限protected :仅类内可以访问,继承后可以访问

#include <iostream> //标准输入输出控件
#include <iomanip>
#include <string>  //使用string声明字符串时必须包含
#include <cstdlib> //汉化
using namespace std;// 构造与析构
class Person
{
private:string name;int age;public:// 有参构造函数Person(const string &name, int age){this->name = name;this->age = age;};// 析构函数~Person() {}; // 对象销毁时清理内存// 向外部提供访问内部属性的方法void getMess(){cout << "构造函数初始化:" << name << age << endl;};
protected:
};int main()
{system("chcp 65001 >nul"); // 汉化// using std::cout;Person p("zhangsan",25);//实例化一个叫张三,25岁的对象cout << p.name << p.age <<endl;return 0;
}

二、构造函数与析构函数

(一)构造函数分类

1.按参数分类 有参数 无参数
2.按类型分类 普通构造 拷贝构造函数拷贝构造函数:Person( const Person &p ){age = p.age;}

(二)构造函数的调用方法

	1.括号法Person p;//无参构造,默认构造Person p1(10);//有参构造Person p2(p1);//拷贝构造2.显示法Person p = Person(10);Person(10);//匿名对象,执行完后系统会立即回收匿名对象Person p = Person(p1);//拷贝构造注意:不要用拷贝构造函数创建初始化一个匿名对象 Person (p1) === Person p13.隐式法Person p = 10; === Person p = Person(10);Person p = P1;//拷贝构造

(三)拷贝构造函数的场景

1.使用一个创建完毕的对象来初始化一个新对象

#include <iostream> //标准输入输出控件
#include <iomanip>
#include <string>  //使用string声明字符串时必须包含
#include <cstdlib> //汉化
using namespace std;class Car
{
private:int carNumber;public:// 构造函数的重构// 默认构造函数,无参构造Car() { cout << "调用无参构造函数" << endl; };// 有参构造Car(int num){carNumber = num;cout << "调用有参构造函数" << endl;};// 拷贝构造Car(const Car &car){carNumber = car.carNumber;cout << "调用拷贝构造函数" << endl;};~Car() { cout << "调用析构函数" << endl; };int getCarNumber(){return carNumber;};protected:
};void test1()
{Car car1;Car car2(10);Car car3(car2);cout << "car2构造结果:" << car2.getCarNumber() << endl;cout << "car3构造结果:" << car3.getCarNumber() << endl;
};int main()
{system("chcp 65001 >nul"); // 汉化// using std::cout;/* 拷贝构造函数的使用场景*/test1(); // 使用一个创建完毕的对象来初始化一个新对象return 0;
}

2.值传递的方式给函数参数传参

#include <iostream> //标准输入输出控件
#include <iomanip>
#include <string>  //使用string声明字符串时必须包含
#include <cstdlib> //汉化
using namespace std;class Car
{
private:int carNumber;public:// 构造函数的重构// 默认构造函数,无参构造Car() { cout << "调用无参构造函数" << endl; };// 有参构造Car(int num){carNumber = num;cout << "调用有参构造函数" << endl;};// 拷贝构造Car(const Car &car){carNumber = car.carNumber;cout << "调用拷贝构造函数" << endl;};~Car() { cout << "调用析构函数" << endl; };int getCarNumber(){return carNumber;};protected:
};void test2_1(Car c1) {};void test2()
{Car c1;test2_1(c1);
};int main()
{system("chcp 65001 >nul"); // 汉化// using std::cout;/* 拷贝构造函数的使用场景*/test2(); // 值传递的方式给函数参数传参return 0;
}

3.用值的方式返回一个局部对象

#include <iostream> //标准输入输出控件
#include <iomanip>
#include <string>  //使用string声明字符串时必须包含
#include <cstdlib> //汉化
using namespace std;class Car
{
private:int carNumber;public:// 构造函数的重构// 默认构造函数,无参构造Car() { cout << "调用无参构造函数" << endl; };// 有参构造Car(int num){carNumber = num;cout << "调用有参构造函数" << endl;};// 拷贝构造Car(const Car &car){carNumber = car.carNumber;cout << "调用拷贝构造函数" << endl;};~Car() { cout << "调用析构函数" << endl; };int getCarNumber(){return carNumber;};protected:
};Car test3_1()
{Car c1;return c1;
};void test3()
{Car c1 = test3_1();/* 正常来说,这里会执行两次拷贝构造函数第一次是返回时,return c1 会先将 c1 拷贝到一个临时对象(调用拷贝函数)第二次是执行 Car c1 = 临时对象,会再将临时对象拷贝到 test3() 中的 c1(再调用一次拷贝构造函数)但编译器会优化这两步复制,直接在 test3() 的 c1 内存位置构造 test3_1() 中的对象在编译时关闭优化(如 GCC 用 -fno-elide-constructors 选项),就能看到拷贝构造函数被调用*/
};int main()
{system("chcp 65001 >nul"); // 汉化// using std::cout;/* 拷贝构造函数的使用场景*/test3(); // 用值的方式返回一个局部对象return 0;
}

(四)构造函数的调用规则

	1.默认情况下编译器至少给一个类提供三个默认构造函数(无参构造,析构函数,拷贝构造)2.写了自定义的有参构造函数后,编译器不提供无参构造函数,但提供拷贝构造函数3.写了自定义构造函数后,编译器不再提供其他构造函数

三、易混淆知识点

(一)class 与 struct 的区别

class的默认访问权限是private
struct的默认访问权限是public

(二)拷贝构造函数的参数可以不用const吗

非 const 引用只能绑定到 “可修改的左值”(如普通变量),无法绑定到常量对象或临时对象

    class Car {public:int id;// 拷贝构造函数:参数为非 const 引用Car(Car& other) {this->id = other.id;}};int main() {Car c1;Car c2 = c1;  // 正确:c1 是可修改的左值,可绑定到非 const 引用const Car c3;  // 常量对象Car c4 = c3;  // 错误:无法用非 const 引用绑定常量对象Car c5 = Car();  // 错误:无法用非 const 引用绑定临时对象(Car() 是临时对象)return 0;}
http://www.dtcms.com/a/536416.html

相关文章:

  • 装修公司前十强郑州做网站优化
  • 绿色网站欣赏站点查询
  • 插件:@vitejs/plugin-basic-ssl
  • Docker使用详解:在ARM64嵌入式环境部署Python应用
  • 【微知】MAC笔记本如何重启tourchbar?(sudo pkill TouchBarServer)
  • Smartproxy API 代理 IP 提取指南——JSON-first 架构与参数化最佳实践
  • 统计过程能力指数在齿轮制造中的应用学习分享
  • 河北地矿建设集团官方网站昆山市网站建设
  • __金仓数据库平替MongoDB实战:制造业生产进度管理的国产化升级之路__
  • 电商设计就是网站设计吗乐清本地生活服务平台
  • html css js网页制作成品——似锦HTML+CSS网页设计(5页)附源码
  • 某教育大厂面试题解析:MySQL索引、Redis缓存、Dubbo负载均衡等
  • wordpress怎么加菜单阿里网站怎样做seo
  • 2025年损坏Excel文件修复工具推荐:一键恢复表格内容
  • 网站一直百度上搜不到是怎么回事素马杭州网站设计介绍
  • 基于 STM32 的智能水表流量计设计与实现 —— 数据采集与远程传输
  • 深度学习核心概念拆解:张量、模型、训练、推理
  • C++初阶 -- 模拟实现list
  • 开源Outline系统基础知识要点及避坑要点
  • 淘宝客云建站官网模板网pi
  • 中国糕点网页设计网站查工程建设不良记录免费的网站
  • redis-cluster集群配置部署
  • 整体设计 全面梳理复盘 之9 “相提并论的三者” :否则段三种主义 “保持 - 反对 - 保留” 表格化构建与原始逻辑对标
  • 第5章-虚拟机栈
  • 配置(1):samba的配置
  • web开发,在线%鲜花销售%管理系统,基于asp.net,webform,c#,sql server存储过程
  • [作品集]-容易宝
  • 数字校园建设专题网站自动化项目外包网
  • python-docx样式
  • 新建网站如何调试seo石家庄