c++ 语法 类和对象

类的特性: 封装,继承,多态

封装:

将属性和行为作为一个整体,表现生活中的事务

将属性和行为加以权限控制

语法

class 类名{访问权限:属性/行为}

//
//  main.cpp
//  cpplearn
//
//  Created by KING on 2024/2/1.
//#include <iostream>
#include "mathutil.hpp"
#include <string>
using namespace std;
const double PI = 3.14;
class Circle {//访问权限public://属性double m_r;//行为double caculate() {return 2 * m_r * PI;}};class Person {// 属性 成员属性 成员变量//行为 成员函数 方法
private:string m_name;int  cardId;int  m_age;
public:string getName() {return m_name;}int getCardId() {return cardId;}void personInfo() {std::cout << m_name << "cardID =" << cardId << std::endl;}void setAge(int age) {if (age < 0 || age > 150) {std::cout << "age shu ru you  wu" << std::endl;return;}m_age = age;}void setName(string name) {m_name = name;}void setId(int id) {cardId = id;}
};int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";// 实例化 通过类创建对象Circle c1;//属性赋值c1.m_r = 10;std::cout << "周长=" << c1.caculate() << std::endl;Person person;person.setName("李斯");person.setId(411323);person.personInfo();std::cout << person.getName() << "cardID =" << person.getCardId() << std::endl;return 0;
}

权限

public: 公共权限:类内类外都可访问

protected  保护权限:类内可以访问 类外不可访问 子类可访问父类保护属性

private 私有权限:类内可以访问 类外不可以访问 子类不能访问父类私有属性

struct 和 class的区别

struct默认权限为公共

class默认权限为私有

demo

#include <iostream>
#include "mathutil.hpp"
#include <string>
using namespace std;
class  Cube{
private:double m_width;double m_height;double m_length;
public:void setHeight(double height) {m_height = height;}void setWidth(double width) {m_width = width;}void setLength(double length){m_length = length;}double getWidth() {return m_width;}double getHeight() {return m_height;}double getLength() {return m_length;}double getarea() {return 2 * m_height * m_width + 2 * m_length * m_height + 2 * m_length * m_width;}double getcubeaV() {return m_width * m_height * m_length;}bool isSamplecube(Cube &c) {if (getWidth() == c.getWidth() && getHeight() == c.getHeight() && getLength() == c.getLength()) {return  true;}return false;}};bool isSampleCube(Cube &c1, Cube &c2) {if (c1.getWidth() == c2.getWidth() && c1.getHeight() == c2.getHeight() && c1.getLength() == c2.getLength()) {return  true;}return false;
}int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";Cube cube;cube.setWidth(10.0);cube.setHeight(13.0);cube.setLength(23.0);std::cout << "面积=" << cube.getarea() << "\t 体积=" << cube.getcubeaV() << std::endl;Cube cube2;cube2.setWidth(10.0);cube2.setHeight(13.0);cube2.setLength(23.0);if (isSampleCube(cube, cube2)) {std::cout  << "cube == cube2" << std::endl;} else {std::cout  << "cube != cube2" << std::endl;}Cube cube3;cube3.setWidth(11.0);cube3.setHeight(16.0);cube3.setLength(28.0);if (cube2.isSamplecube(cube3)) {std::cout  << "cube2 == cube3" << std::endl;} else {std::cout  << "cube3 != cube2" << std::endl;}return 0;
}

  类内有其他类作为成员变量

   

#include <iostream>
#include "mathutil.hpp"
#include <string>
using namespace std;
class Point {
private:double m_x;double m_y;
public:void setX(double x) {m_x = x;}void setY(double y) {m_y = y;}double getX() {return m_x;}double getY() {return m_y;}
};
class Circle1 {
private:double m_r;Point  m_point;public:void setR(double r) {m_r = r;}void setPoint(Point point) {m_point = point;}double getR() {return m_r;}Point getPoint() {return m_point;}
};
void isInCircle(Circle1 &circle, Point &point) {double distance = (circle.getPoint().getX() - point.getX()) *  (circle.getPoint().getX() - point.getX()) + (circle.getPoint().getY() - point.getY()) * (circle.getPoint().getY() - point.getY());double mr = circle.getR() * circle.getR();if (distance == mr) {std::cout << "点在圆上" << std::endl;} else if (distance < mr) {std::cout << "点在圆内" << std::endl;} else {std::cout << "点在圆外" << std::endl;}
}
int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";Point center;center.setX(10.0);center.setY(0.0);Circle1 circle;circle.setR(10.0);circle.setPoint(center);Point point;point.setX(-1.0);point.setY(0.0);isInCircle(circle, point);return 0;
}

构造函数析构函数

构造函数初始化类

析构函数销毁类资源

对象的初始化和清理工作是由编译器强制要求我们做的 因此我们如果不提供构造函数和析构函数编译器会提供 编译器提供的构造和析构函数是空实现

构造函数: 主要用于创建对象时为对象的成员属性赋值 构造函数由编译器自动调用无需手动调用

析构函数: 主要作用于对象销毁前系统自动调用 执行一些清理工作。

构造函数语法:

类名(){}

1.构造函数没有返回值也不用写void

2.函数名称与类名相同

3.构造函数可以有参数 因此可以重载

4.程序在调用对象的时候会自动调用构造函数 无需手动调用 并且只调用一次。

析构函数语法

1.析构函数没有返回值也不用写void

2.函数名称与类名相同在类名前面加上~

3.析构函数有没有参数 因此不可以重载

4.程序对象销毁前会自动调用析构函数 无需手动调用 并且只会调用一次。

.h文件

#ifndef People_hpp
#define People_hpp#include <stdio.h>
class People {
public:People();~People();};#endif /* People_hpp */

.cpp文件

#include "People.hpp"
#include <iostream>
People:: People() {std::cout << "people 构造函数调用了" << std::endl;
}People:: ~People() {std::cout << "people 析构函数调用了" << std::endl;}

调用

#include <iostream>
#include "People.hpp"
using namespace std;
int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";People people;People p = People();return 0;
}

构造函数的分类和调用

按参数分类: 有参构造函数和无参构造函数

按类型分类:普通构造函数和拷贝构造函数

调用方式

1.括号调用

2.显式调用

3.隐式转换法

#ifndef People_hpp
#define People_hpp#include <stdio.h>
class People {int m_age;
public:// 有参构造People(int age);//无参构造People();//拷贝构造People(const People  &p);~People();};#endif /* People_hpp */
#include "People.hpp"
#include <iostream>
//无参构造 或者默认构造函数
People:: People() {std::cout << "people 构造函数调用了。无参构造 或者默认构造函数" << std::endl;
}People:: ~People() {std::cout << "people 析构函数调用了" << std::endl;}// 有参构造
People:: People(int age) {m_age = age;std::cout << "people 构造函数调用了。  有参构造" << std::endl;
}//拷贝构造
People:: People(const People &p) {m_age = p.m_age;std::cout << "people 构造函数调用了。 拷贝构造" << std::endl;}
#include <iostream>
#include "People.hpp"
using namespace std;
int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";// 默认构造函数调用// 括号调用法People p1; // 默认构造函数 注意调用的时候不需要使用小括号 否则编译器会把它当成函数声明People p()People p2(25);People p3(p2);//显式法People p4 = People(10); // 有参构造People p5 = People(p4); // 拷贝构造//People(22); // 匿名对象 当前行执行结束后系统会立即回收其内存// 不要用拷贝对象初始化一个匿名构造函数 编译器会认为是重定义  People(p5)//隐式转换People p6 = 10; //相当于 People p6 = People(10); 有参构造People p7 = p6; // 拷贝构造return 0;
}
拷贝构造的使用场景

1.使用已经创建完成的对象创建一个新对象

    People p4 = People(10); // 有参构造People p5 = People(p4); // 拷贝构造

2.值传递的方式给函数参数传值. (调用函数传值的时候 实参给形参赋值的时候)

#include <iostream>
#include "People.hpp"
using namespace std;
void peopleInfo(People p) {std::cout << "peopleInfo!\n" << std::endl;}
int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";People p;peopleInfo(p);return 0;
}Hello, World!
people 构造函数调用了。无参构造 或者默认构造函数
people 构造函数调用了。 拷贝构造
peopleInfo!people 析构函数调用了
people 析构函数调用了
Program ended with exit code: 0

3.值返回局部对象

#include <iostream>
#include "mathutil.hpp"
#include <string>
#include "People.hpp"
using namespace std;People createPeople() {People p;std::cout <<  &p << std::endl;return p;
}
void test22() {People p1 = createPeople();std::cout <<  &p1 << std::endl;}
int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";test22();return 0;
}Hello, World!
people 构造函数调用了。无参构造 或者默认构造函数
0x7ff7bfeff238
0x7ff7bfeff238
people 析构函数调用了
sh: pause: command not found
Program ended with exit code: 0

    我在xcode上没有试出来  可能不同编译器 处理的不同吧

构造函数调用规则

默认情况下cpp给一个类提供三个函数

1.默认构造函数 函数体为空

2.析构函数 函数体为空

3.默认拷贝构造函数 对属性进行值拷贝

规则

如果自定义了有参构造函数 c++不再提供默认构造函数 但是会提供默认拷贝构造函数

如果自定义了拷贝构造函数 c++不再提供其他构造函数。

深浅拷贝

 使用编译器生层的拷贝构造函数 浅拷贝

 这样在析构释放堆区内存的时候就会crash

#ifndef Phone_hpp
#define Phone_hpp#include <stdio.h>
class Phone {
private:double m_width;double* m_height;
public:Phone(double width,double height);~Phone();
};
#endif /* Phone_hpp */
#include "Phone.hpp"
#include <iostream>Phone::Phone(double width,double height) {m_width = width;m_height = new double(height);std::cout << "Phone 构造函数调用了。  有参构造" << std::endl;}Phone::~Phone() {// 清理堆区开辟的内存if (m_height != NULL) {delete m_height;m_height = NULL;}std::cout << "Phone 析构函数调用了" << std::endl;}
#include <iostream>
#include "Phone.hpp"
using namespace std;
void test23() {Phone phone(16,20);Phone p(phone);}int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";test23();std::cout << "end!\n";return 0;
}Hello, World!
Phone 构造函数调用了。  有参构造
Phone 析构函数调用了
cpplearn(5538,0x7ff85f8bc680) malloc: *** error for object 0x600000010030: pointer being freed was not allocated
cpplearn(5538,0x7ff85f8bc680) malloc: *** set a breakpoint in malloc_error_break to debug
(lldb) 

深拷贝 解决类中有在堆区开辟内存的 一定要自己实现拷贝构造函数 防止浅拷贝析构 释放堆区内存时候crash

#ifndef Phone_hpp
#define Phone_hpp#include <stdio.h>
class Phone {
private:double m_width;double* m_height;
public:Phone(double width,double height);Phone(const Phone &p);~Phone();
};
#endif /* Phone_hpp */
#include "Phone.hpp"
#include <iostream>Phone::Phone(double width,double height) {m_width = width;m_height = new double(height);std::cout << "Phone 构造函数调用了。  有参构造" << std::endl;}
/// 当类中有指针类型的时候 就需要自己实现拷贝构造函数
Phone::Phone(const Phone &p) {m_width = p.m_width;m_height =  new double(*p.m_height);std::cout << "Phone 拷贝构造函数调用了。" << std::endl;
}Phone::~Phone() {// 清理堆区开辟的内存if (m_height != NULL) {delete m_height;m_height = NULL;}std::cout << "Phone 析构函数调用了" << std::endl;}
#include <iostream>
#include "Phone.hpp"
using namespace std;
void test23() {Phone phone(16,20);Phone p(phone);}int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";test23();std::cout << "end!\n";return 0;
}Hello, World!
Phone 构造函数调用了。  有参构造
Phone 拷贝构造函数调用了。
Phone 析构函数调用了
Phone 析构函数调用了
end!
Program ended with exit code: 0

初始化列表

用来初始化属性

构造函数():属性1:(值1)属性2:(值2)...{}

#include <iostream>
#include <string>
using namespace std;
class Car{
private:string m_name;string m_color;double m_version;
public:Car(string name, string color, double version): m_name(name), m_color(color), m_version(version) {std::cout << "name = " << m_name << "color = " << m_color << "version = " << m_version << std::endl;};~Car() {std::cout << "~Car()\n";}
};int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";Car car("bmw","black",8.1);std::cout << "end!\n";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663773.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity角色触摸转向

1、挂载脚本到角色的父物体A上 2 、以屏幕左边的触摸为移动&#xff0c;右边为转向操作 3、加载角色时&#xff0c;将角色的父物体设置为A&#xff0c;须将角色的位置和角度置0 using System; using System.Collections; using System.Collections.Generic; using UnityEngin…

Springboot校验注解

Spring Boot 提供了一组基于 Hibernate Validator 的校验注解&#xff0c;用于验证请求参数、实体对象等数据的合法性。下面是一些常用的 Spring Boot 校验注解及其功能&#xff1a; 导入依赖 <dependency><groupId>org.springframework.boot</groupId><…

Redis核心技术与实战【学习笔记】 - 8.Redis 时间序列数据处理

在做 web 产品是&#xff0c;都会有这么一个需求&#xff1a; 记录用户在网站或 APP 上的点击行为数据&#xff0c;来分析用户行为。这里的数据一般包括用户 ID、行为类型&#xff08;如浏览、登录、下单等&#xff09;、行为发生的时间戳。 userID, type, timeStamp 与之类似&…

基于WordPress开发微信小程序1:搭建Wordpress

2年前&#xff0c;在知乎上提问&#xff1a;多数公司为什么宁愿自研也不用wordpress二次开发建站&#xff1f; - 知乎 (zhihu.com)&#xff0c;收到了&#xff0c;很多回答 自己打算做一下提升&#xff0c;便有了自己基于wordpress开发微信小程序的想法 项目定位 基于wordpre…

渗透测试之信息收集下篇

华子目录 查找真实IP多地ping确认是否使用CDN查询历史DNS解析记录DNSDB微步在线Ipip.netviewdns phpinfo绕过CDN 旁站和C段站长之家google hacking网络空间搜索引擎在线C段C段利用脚本Nmap,Msscan扫描等常见端口表 网络空间搜索引擎FOFA的常用语法 扫描敏感目录/文件御剑7kbsto…

Oracle 面试题 | 08.精选Oracle高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

软考18-上午题-线性结构

一、线性结构 线性结构是一种逻辑结构。 特点&#xff1a;一个出度 一个入度&#xff08;一个接一个排列&#xff09; 1-1、线性表 最简单&#xff0c;最基本的线性结构。 定义&#xff1a;n&#xff08;n > 0&#xff09;个元素的有限序列。 特点&#xff1a; 线性表…

如何读论文

如何读论文 0. 目的 单篇文章从头读到尾&#xff0c;可以&#xff1b; 世界上那么多篇文章&#xff0c; 都这样读&#xff0c; 时间上划不来。 适合你的文章就那么一小撮。 paper 的八股文结构&#xff1a; titleabstractintromethodexpconclusion 1. 第一遍 海选&#…

152基于matlab的GUI滚动轴承特征频率计算

基于matlab的GUI滚动轴承特征频率计算&#xff0c;输入轴承参数&#xff0c;包括转速&#xff0c;节圆直径、滚子直径、滚子数、接触角&#xff0c;就可得滚动特征频率结果&#xff0c;程序已调通&#xff0c;可直接运行。 152 matlab 轴承特征频率 GUI (xiaohongshu.com)

react-activation实现缓存,且部分页面刷新缓存,清除缓存

1.安装依赖 npm i -S react-activation2.使用AliveScope 包裹根组件 import { AliveScope } from "react-activation" <AliveScope><Router><Switch><Route exact path"/" render{() > <Redirect to"/login" push …

代码随想录 Leetcode222.完全二叉树的节点个数

题目&#xff1a; 代码&#xff08;首刷自解 2024年1月30日&#xff09;&#xff1a; class Solution { public:int countNodes(TreeNode* root) {int res 0;if (root nullptr) return res;queue<TreeNode*> deque;TreeNode* cur root;deque.push(cur);int size 0;w…

Shopee菲律宾选品:如何找到畅销产品并提高销售业绩

在电子商务行业中&#xff0c;产品的选择是取得成功的关键之一。对于在Shopee菲律宾平台上销售的卖家来说&#xff0c;找到畅销产品是至关重要的。本文将介绍一些有效的方法&#xff0c;帮助卖家在Shopee菲律宾平台上选择热销产品&#xff0c;并提高销售业绩。 先给大家推荐一…

【Linux】理解系统中一个被打开的文件

文件系统 前言一、C语言文件接口二、系统文件接口三、文件描述符四、struct file 对象五、stdin、stdout、stderr六、文件描述符的分配规则七、重定向1. 重定向的原理2. dup23. 重谈 stderr 八、缓冲区1. 缓冲区基础2. 深入理解缓冲区3. 用户缓冲区和内核缓冲区4. FILE 前言 首…

169. 多数元素-面试经典150

给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1&#xff1a; 输入&#xff1a;nums [3,2,3] 输出&#xff1a;3 示例 …

25考研|660/880/1000/1800全年带刷计划

作为一个参加过两次研究生考试的老学姐&#xff0c;我觉得考研数学的难度完全取决于你自己 我自己就是一个很好的例子 21年数学题目是公认的简单&#xff0c;那一年考130的很多&#xff0c;但是我那一年只考了87分。但是22年又都说是有史以来最难的一年&#xff0c;和20年的难度…

Entity实体设计

Entity实体设计 &#x1f4a1;用来和数据库中的表对应&#xff0c;解决的是数据格式在Java和数据库间的转换。 &#xff08;一&#xff09;设计思想 数据库Java表类行对象字段&#xff08;列&#xff09;属性 &#xff08;二&#xff09;实体Entity编程 编码规范 &#x1f4a…

谈谈BlueStore

目录 未完待续前言组成前期准备工作基础概念对象PextentextentBlobNode 线程事务磁盘的抽象与分配位图法分层位图 上电流程写流程读流程参考资料 未完待续 前言 BlueStore是什么&#xff1f; Ceph是一个统一的分布式存储系统。BlueStore是Ceph的存储引擎。 它的作用是什么&am…

【Go语言成长之路】引入外部包

文章目录 引入外部包一、查找需要引用的包二、引入需要导入的包三、运行程序 引入外部包 ​ 实现Demo: 引用rsc.io/quote包来实现打印输出 一、查找需要引用的包 ​ 比如说我现在想要找一个quote的包&#xff0c;那么可以通过如下步骤进行操作&#xff1a; 访问pkg.go.dev,并…

服务器运行中发生脚本错误怎么办

在服务器运行过程中&#xff0c;由于各种原因&#xff0c;可能会出现脚本错误。这些错误可能源于编程错误、不兼容的库或依赖项&#xff0c;或者不良的服务器环境配置。这些错误可能会导致服务器的正常运行受到影响&#xff0c;甚至导致整个网站或应用程序的崩溃。因此&#xf…

2024美赛数学建模E题思路分析 - 财产保险的可持续性

1 赛题 问题E&#xff1a;财产保险的可持续性 极端天气事件正成为财产所有者和保险公司面临的危机。“近年来&#xff0c;世界已经遭受了1000多起极端天气事件造成的超过1万亿美元的损失”。[1]2022年&#xff0c;保险业的自然灾害索赔人数“比30年的平均水平增加了115%”。[…