cpp_05_类_string类

news2024/11/19 10:25:01

1  类的定义

1.1   构造函数

        定义:函数名必须与类名相同,且没有返回值类型 ,连void也没有。

        构造函数调用时间:

        在定义对象的同时自动被调用,而且仅被调用一次

                1)对象定义语句

                2)new操作符

        构造函数的作用:

                1)设置  对象的初始状态:定义对象的各个成员变量赋初值

                2)执行  在对象定义之初想实现的任何操作 。

// clsobj1.cpp
// 构造函数:(1)函数名必须与类名相同 (2)没有返回值类型
// 构造函数被调用的时间:定义对象的同时,自动被调用
// 构造函数的作用:定义对象的各个成员变量(造包子馅)
#include <iostream>
#include <cstring>
using namespace std;
class Human {
public:
    Human( /* Human* this */ int age=0, const char* name="无名") {
        // 在this所指向的内存空间中 定义m_age(给m_age分配内存空间),初值随机数
        // 在this所指向的内存空间中 定义m_name(给m_name分配内存空间),初值随机数
        cout << "Human类的构造函数被调用" << endl;
        m_age = age;
        strcpy( m_name, name );
    }
//    void setinfo( /* Human* this */ int age=0, const char* name="无名" ) { 
//        this->m_age = age;
//        strcpy( this->m_name, name ); 
//    }
    void getinfo( /* Human* this */ ) { 
        cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
    }
private:    
    int m_age; // 声明
    char m_name[256]; // 声明 
};
// 以上代码模拟类的设计者(标准库的类,第三方提供的类,自己设计的类)
// ------------------------
// 以下代码模拟类的使用者
int main( void ) {
    Human h(22,"张飞"); // 定义h (给h分配内存空间),利用h.Human(22,"张飞")

    cout << "h对象创建完毕" << endl; 
//    h.setinfo( 22,"zhangfei" ); 
    h.getinfo(); 
    return 0;

1.2  对象的定义过程

        定义对象,就是

        1)给对象分配内存空间

        2)并利用对象调用构造函数

                        ①定义成员变量;

                        ②执行用户在构造函数中书写的代码。

        

2  类的实例化(定义对象)的11种方法

2.1  栈中,对象的定义和销毁

        在栈中,定义单个对象:

                01)类名  对象;    //注意不要加空括号,加了误导编译器:返回值类型 函数名 形参表

                02)类名  对象( 实参表 ); 

        在栈中,定义对象数组:

                03)类名  对象数组[ 元素个数 ]; 

                04)类名  对象数组[ 元素个数 ] = { 类名( 实参表 ), ... };    // 11)定义匿名对象,右值

                05)类名  对象数组[] = { 类名( 实参表 ), ...}; 

2.2  堆中,对象的定义和销毁

        不是所有的匿名对象生命周期都短暂:new出来的对象(下面讲到),基类子对象

        匿名的栈对象,生命周期短暂,语句级。

        

        在堆中,定义/销毁单个对象

                06)类名*  对象指针 = new  类名;  //定义相应类的堆对象,匿名对象。

                07)类名*  对象指针 = new  类名();  //这里可以加空括号,同06,异于01

                08)类名*  对象指针 = new  类名( 实参表 ); 

                        delete  对象指针;

        在堆中,定义/销毁对象数组

                09)类名*  对象数组指针 = new  类名[ 元素个数 ]; 

                10)类名* 对象数组指针 = new  类名[ 元素个数 ]{类名( 实参表 ), ...};     // 11标准

                        delete[]  对象数组指针;

// clsobj2.cpp 定义对象的11种方法
#include <iostream>
#include <cstring>
using namespace std;
class Human {
public:
    Human( /* Human* this */ int age=0, const char* name="无名") {
        // 在this所指向的内存空间中 定义m_age(给m_age分配内存空间),初值随机数
        // 在this所指向的内存空间中 定义m_name(给m_name分配内存空间),初值随机数
        cout << "Human类的构造函数被调用" << endl;
        m_age = age;
        strcpy( m_name, name );
    }
    void getinfo( /* Human* this */ ) { 
        cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
    }
private:    
    int m_age; // 声明
    char m_name[256]; // 声明 
};
// 以上代码模拟类的设计者(标准库的类,第三方提供的类,自己设计的类)
// ------------------------
// 以下代码模拟类的使用者
int main( void ) {
    Human(32,"马超").getinfo();

    Human h(22,"张飞"); // 定义h (给h分配内存空间),利用h.Human(22,"张飞")
    h.getinfo(); 

    Human h2; // 定义h2,利用h2.Human()
    h2.getinfo();

    Human h3[3]; // 定义了3个Human类对象,并分别利用这3个Human类对象.Human()
    for( int i=0; i<3; i++ ) {
        h3[i].getinfo();
    }

    Human h4[3] = { Human(22,"张飞"), Human(20,"赵云"), Human(25,"关羽") };
    for( int i=0; i<3; i++ ) {
        h4[i].getinfo();
    }

    Human h5[] = { Human(22,"张飞"), Human(20,"赵云"), Human(25,"关羽"), Human(45,"黄忠") };
    for( int i=0; i<sizeof(h5)/sizeof(h5[0]); i++ ) {
        h5[i].getinfo();
    }

    Human* ph = new Human; // 定义 Human类堆对象,利用 Human类堆对象.Human()
    (*ph).getinfo(); // ph->getinfo()
    delete ph;
    ph = NULL;

    Human* ph2 = new Human(); // 定义 Human类堆对象,利用 Human类堆对象.Human()
    (*ph2).getinfo();
    delete ph2;
    ph2 = NULL;

    Human* ph3 = new Human(18,"武松"); // 定义 Human类堆对象,利用 Human类堆对象.Human(18,"武松")
    (*ph3).getinfo();
    delete ph3;
    ph3 = NULL;

    Human*ph4 = new Human[3]; // 定义了 3个Human类堆对象,分别利用这3个Human类堆对象.Human()
    for( int i=0; i<3; i++ ) {
        ph4[i].getinfo();
    }
    delete[] ph4;
    ph4 = NULL;

    Human* ph5 = new Human[3]{ Human(18,"武松"), Human(19,"李逵"), Human(20,"鲁达") };
    for( int i=0; i<3; i++ ) {
        ph5[i].getinfo();
    }
    delete[] ph5;
    ph5 = NULL;

    return 0;
}

3  string类

        是C++标准库中的类,在操作字符串方面优于char*  []  :

                1)string类是c++类,而char* []的c痕迹明显;

                2)string类可直接 = 赋值/初始化,而char* []要用strcpy()。

3.1  string类的5种使用方法

        string  s1( "hello" );           //触发构造函数

        string  s2( s1 );                 // 等同于 string  s2 = s1;    触发构造函数

        string  s3;    s3 = s2;        // 触发拷贝复制函数调用

        string  s4 = "hello";          // 触发类型转换操作

        string  s5;    s5 = "hello";        // 触发类型转换操作

// string_pre.cpp C++标准库设计的string类
#include <iostream>
using namespace std;

// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {
    string s1("hello"); // s1维护的字符串为"hello"
    cout << "s1:" << s1 << endl;

    // 如果在做初始化,并且“=”两边类型完全一致,那么=xxx 和 (xxx) 无差别
    
    string s2(s1); // = s1; // s2维护的字符串 和 s1维护的字符串 内容相同 
    cout << "s2:" << s2 << endl;
    
    string s3; // s3维护的字符串为空串
    cout << "s3被赋值前:" << s3 << endl;
    s3 = s2; // s3维护的字符串 和 s2维护的字符串 内容相同
    cout << "s3被赋值后:" << s3 << endl;

    // 只要“=”两边类型不一致,编译器首先要做类型转换操作

    string s4 = "hello"; // s4维护的字符串内容为"hello"
    cout << "s4:" << s4 << endl;
    
    string s5; // s5维护的字符串为空串
    s5 = "hello"; // s5维护的字符串内容为 "hello"
    cout << "s5:" << s5 << endl;
    return 0;
}

 

3.2  string类的内部实现原理

//string.cpp
#include <iostream>
using namespace std;

// C++标准库设计的string类(类中有一个私有成员变量 char*m_psz-->指向一个字符串)

// 模拟类的设计者(类库、别人设计的类、自己设计的类)
// --------------------------------
// 模拟用户(使用类的人)
int main( void ) {
    string s1("hello"); // 定义s1,利用s1.string("hello")--->s1维护的字符串为"hello"
    cout << "s1:" << s1 << endl;

    // 如果在做初始化,并且“=”两边类型完全一致,那么=xxx 和 (xxx) 无差别
    
    string s2 =s1; //(s1) // 定义s2,利用s2.string(s1)--->s2维护的字符串 和 s1维护的字符串 内容相同 
    cout << "s2:" << s2 << endl;
    
    string s3; // 定义s3,利用s3.string()--->s3维护的字符串为空串
    cout << "s3被赋值前:" << s3 << endl;

    // 如果在做赋值,并且“=”两边类型完全一致,那么将触发 operator= 函数的调用
    s3 = s2; // s3.operator=(s2) --->s3维护的字符串 和 s2维护的字符串 内容相同
    cout << "s3被赋值后:" << s3 << endl;

    // 不管是初始化还是赋值,只要“=”两边类型不一致,编译器首先要做类型转换操作

    string s4 = "hello"; 
    // 定义 匿名string类对象,利用 匿名string类对象.string("hello")--->匿名string类对象维护的字符串为"hello"
    // string s4 = 匿名string类对象--->s4维护的字符串 和 匿名string类对象维护的字符串 内容相同
    // --->s4维护的字符串内容为"hello"
    //模式相当于s1 + s2
    cout << "s4:" << s4 << endl;
    
    string s5; // 定义s5,利用s5.string() --->s5维护的字符串为空串
    s5 = "hello"; 
    // 定义 匿名string类对象,利用 匿名string类对象.string("hello")--->匿名string类对象维护的字符串为"hello"
    // s5 = 匿名string类对象--->s5维护的字符串 和 匿名string类对象维护的字符串 内容相同
    //--->s5维护的字符串内容为 "hello"
    cout << "s5:" << s5 << endl;
    return 0;
}

// twoDimensional.cpp 设计一个二维坐标系的 类
#include <iostream>
using namespace std;

class TwoDimensional {
public:
    TwoDimensional( int x=0, int y=0 ) {
        // 在this指向的内存空间中 定义m_x初值为随机数
        // 在this指向的内存空间中 定义m_y初值为随机数
        m_x = x;
        m_y = y;
    }
    void getinfo( /* TwoDimensional* this */ ) { // 非常函数
        cout << "横坐标: " << m_x << ", 纵坐标: " << m_y << endl;
    }
private:
    int m_x; // 横坐标
    int m_y; // 纵坐标
};

int main( void ) {
    TwoDimensional a(100,300); // 定义a,利用a.TwoDimensional(100,300)
    a.getinfo( );

    return 0;
}

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

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

相关文章

20231226在Firefly的AIO-3399J开发板上在Android11下调通后摄像头ov13850

20231226在Firefly的AIO-3399J开发板上在Android11下调通后摄像头ov13850 2023/12/26 8:22 开发板&#xff1a;Firefly的AIO-3399J【RK3399】 SDK&#xff1a;rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2.ab And…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)EventLoop初始化

这个Dispatcher是一个事件分发模型&#xff0c;通过这个模型,就能够检测对应的文件描述符的事件的时候,可以使用epoll/poll/select,前面说过三选一。另外不管是哪一个底层的检测模型,它们都需要使用一个数据块,这个数据块就叫做DispatcherData。除此之外,还有另外一个部分,因为…

idea导入spring-framework异常:error: cannot find symbol

从github上clone代码spring-framework到本地后导入idea&#xff0c;点击gradle构建后控制台提示异常&#xff1a; 具体异常信息&#xff1a; /Users/ZengJun/Desktop/spring-framework/buildSrc/src/main/java/org/springframework/build/KotlinConventions.java:44: error:…

智能优化算法应用:基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于侏儒猫鼬算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.侏儒猫鼬算法4.实验参数设定5.算法结果6.…

【操作系统】探究文件系统奥秘:创建proc文件系统的解密与实战

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;Linux专栏&#xff1a;《探秘Linux | 操作系统解密》⏰诗赋清音&#xff1a;月悬苍穹泛清辉&#xff0c;梦随星河徜徉辉。情牵天际云千层&#xff0c;志立乘风意自飞。 ​ 目录 &a…

编译原理-----逆波兰表示法,四元式,三元式,间接三元式

目录 逆波兰表达式 四元式 三元式 间接三元式 逆波兰表达式 逆波兰表示法即后缀表达式&#xff0c;而后缀表达式需要注意&#xff1a; ①遵循从外向内进行分析 ②由算数优先符从低到高进行拆分&#xff0c;例如&#xff1a; 我们以“-”号作为分隔进行拆分&#xff0c;…

STM32逆变器方案

输入电压&#xff1a; 额定输入电压&#xff1a;DC110V 输入电压范围&#xff1a;DC77-137.5V 额定输出参数 电压&#xff1a;200V5%&#xff08;200VAC~240VAC 可调&#xff09; 频率&#xff1a; 42Hz0.5Hz&#xff08;35-50 可调&#xff09; 额定输出容量&#xff1a;1…

LNPMariadb数据库分离|web服务器集群

LNP&Mariadb数据库分离&#xff5c;web服务器集群 网站架构演变单机版LNMP独立数据库服务器web服务器集群与Session保持 LNP与数据库分离1. 准备一台独立的服务器&#xff0c;安装数据库软件包2. 将之前的LNMP网站中的数据库迁移到新的数据库服务器3. 修改wordpress网站配置…

【SpringBoot篇】解决缓存击穿问题② — 基于逻辑过期方式

&#x1f38a;专栏【SpringBoot】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f38d;什么是逻辑过期方式⭐思路&#x1f339;代码 &am…

Spring实战系列(三)了解容器的基本实现

我们可以通过GitHub或者码云下载spring-framework源码&#xff0c;这边是基于5.X版本进行下载学习的。 地址&#xff1a;https://github.com/spring-projects/spring-framework 分析Spring源码是非常一件的难的事情&#xff0c;只能一步步学习&#xff0c;一步步记录。 前面在…

人工智能的弱点有哪些?

尽管人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;在许多领域取得了巨大的进展和成就&#xff0c;但它仍然存在一些弱点和挑战。以下是人工智能的一些常见弱点&#xff1a; 1. 数据依赖性&#xff1a;人工智能算法通常需要大量的高质量数据进行训练…

每日一题(LeetCode)----二叉树-- 二叉树的右视图

每日一题(LeetCode)----二叉树-- 二叉树的右视图 1.题目&#xff08;199. 二叉树的右视图&#xff09; 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,nu…

flex--伸缩性

1.flex-basis flex-basis 设置的是主轴方向的基准长度&#xff0c;会让宽度或高度失效。 备注&#xff1a;主轴横向&#xff1a;宽度失效&#xff1b;主轴纵向&#xff1a;高度失效 作用&#xff1a;浏览器根据这个属性设置的值&#xff0c;计算主轴上是否有多余空间&#x…

微信小程序picker组件扩展选择时间到秒插件

创建插件seldatetime // 插件JS部分 Component({// 一些选项options: {// 样式隔离&#xff1a;apply-shared 父影响子&#xff0c;shared父子相互影响&#xff0c; isolated相互隔离styleIsolation:"isolated",// 允许多个插槽multipleSlots: true},// 组件的对外属…

k8s的二进制部署(一)

k8s的二进制部署&#xff1a;源码包部署 环境&#xff1a; k8smaster01: 20.0.0.71 kube-apiserver kube-controller-manager kube-schedule ETCD k8smaster02: 20.0.0.72 kube-apiserver kube-controller-manager kube-schedule Node节点01: 20.0.0.73 kubelet kube-pr…

2008年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

今天我们来看看2008年AMC8竞赛的五道典型考题。欢迎您查看历史文章了解之前各年的真题解析&#xff0c;本系列会持续更新&#xff0c;直到大家参加完2024年的比赛。您有任何关于AMC8比赛的任何问题都可以问我&#xff0c;关于题目的解析也可以交流。 【推荐】为帮助孩子们更便…

人工智能_机器学习076_Kmeans聚类算法_体验_亚洲国家队自动划分类别---人工智能工作笔记0116

我们开始来看聚类算法 可以看到,聚类算法,其实就是发现事物之间的,潜在的关联,把 有关联的数据分为一类 我们先启动jupyter notebook,然后 我们看到这里我们需要两个测试文件 AsiaFootball.txt里面记录了,3年的,亚洲足球队的成绩

C语言转WebAssembly的全流程,及测试

第一步&#xff1a;安装环境 参考网址&#xff1a;https://emscripten.org/docs/getting_started/downloads.html 具体过程&#xff1a; 克隆代码&#xff1a;git clone https://github.com/emscripten-core/emsdk.git进入代码目录&#xff1a;cd emsdk获取最新远端代码&…

阿赵UE学习笔记——5、创建关卡元素

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   之前介绍了从空白模板创建关卡&#xff0c;接下来尝试着在这个空白的世界里面&#xff0c;创建一些内容。 一、创建地面 1、创建面片作为地面 创建——形状——平面&#xff0c;可以创建一个面片 在细节面板设置合适的…

深入了解云原生:定义与特征解析

文章目录 一、云原生概述1.1 什么是云原生1.2 云原生组成要素1.3 补充资料 二、云原生的目标2.1 云原生关键目标2.2 云原生特性 三、云原生应用 VS 传统单体应用参考资料 一、云原生概述 1.1 什么是云原生 (1)云原生定义 云原生(Cloud Native) 是一种软件架构和开发方法论&a…