C++自定义String类

自定义一个String类型,该类包含一个指向字符串的指针和一个统计对象数量的计数器.

代码如下:

cpp 复制代码
//string.h
#pragma once
//String类型
#include <iostream>
using namespace std;

class String
{
private:
    char* m_str;//保存字符串的地址
    static int num_strings;//创建的对象数量
public:
    String(const char* str = NULL);//构造函数
    ~String();//析构函数
    String(const String& s);//拷贝构造函数
    String& operator=(const String& s);//=重载函数
    friend ostream& operator<<(ostream & os,const String &s);//重载<<
};
cpp 复制代码
//string.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "string.h"
#include <cstring>

int String::num_strings = 0;//类中的变量

String::String(const char* str)//构造函数
{
    if (str == NULL)
    {
        m_str = new char[strlen("趣字节") + 1];
        strcpy(m_str,"趣字节");
    }
    else
    {
        m_str = new char[strlen(str) + 1];
        strcpy(m_str,str);
    }
    ++num_strings;
    cout << "构造函数:" << m_str << ",对象数量:" << num_strings << endl;//不重要的输出
}
String::~String() //析构函数
{
    delete[]m_str; 
    m_str = NULL;
    --num_strings;
    cout << "析构函数:"  << "对象数量:" << num_strings << endl;//不重要的输出
}

String::String(const String& s)//拷贝构造函数
{
    m_str = new char[strlen(s.m_str) + 1];
    strcpy(m_str,s.m_str);
    ++num_strings;
    cout << "拷贝构造函数:" << m_str << ",对象数量:" << num_strings << endl;//不重要的输出
}
String& String::operator=(const String& s)//=重载函数
{
    if (&s == this)
        return *this;
    delete[]m_str;
    m_str = new char[strlen(s.m_str)+1];
    strcpy(m_str,s.m_str);
    cout << "=赋值函数:" << m_str << ",对象数量:" << num_strings << endl;//不重要的输出
    return *this;
}

ostream& operator<<(ostream& os, const String& s)//重载<<
{
    os << s.m_str << endl;
    return os;
}
cpp 复制代码
//test.cpp测试代码
#include"string.h"

int main()
{
    String s1("趣字节,有趣的编程!");

    String s2(s1);
    String s3 = s1;
    String s4 = String(s1);
    String* ps4 = new String(s1);
    String s5;
    s5 = s1;

    delete ps4;

    return 0;
}

何时调用拷贝(复制)构造函数?下面4中情况都将调用拷贝构造函数:

cpp 复制代码
String s2(s1);                 //1.调用拷贝构造函数
String s3 = s1;                //2.调用拷贝构造函数
String s4 = String(s1);        //3.调用拷贝构造函数
String* ps4 = new String(s1);  //4.调用拷贝构造函数

第1种情况是调用拷贝构造函数的典型写法;

第2种情况不是先定义s3然后再把s1赋值给s3,在初始化阶段这两步合并成拷贝构造函数;注意和s5的区别。

第3种情况,可能调用拷贝构造函数直接创建s4,也可能使用拷贝构造函数生成一个临时对象,然后再赋值给s4,这取决于编译器的具体实现,但我们使用的编译器都是直接调用拷贝构造函数直接创建s4;

第4种,调用拷贝构造创建一个匿名对象,然后把对象的地址赋给ps4指针。

ps4是通过new创建的,在程序结束前必须调用delete释放,delete ps4时会调用ps4的析构函数。

s1,s2,s3,s3,s5都是局部变量,当main函数结束时生命周期自动结束,分别调用自己的析构函数。由于局部变量在栈中,栈的特点是后进先出,所以析构的顺序是s5,s4,s3,s2,s1。

相关推荐
王有品几秒前
python之爬虫入门实例
开发语言·爬虫·python
一水鉴天4 分钟前
为AI聊天工具添加一个知识系统 之135 详细设计之76 通用编程语言 之6
开发语言·人工智能·架构
m0_7482475516 分钟前
数据库系统架构与DBMS功能探微:现代信息时代数据管理的关键
java·开发语言·数据库
环能jvav大师33 分钟前
Electron桌面应用开发:自定义菜单
开发语言·前端·javascript·windows·electron
一水鉴天44 分钟前
为AI聊天工具添加一个知识系统 之136 详细设计之77 通用编程语言 之7
开发语言·人工智能·架构
一只小小汤圆44 分钟前
c++ std::tuple用法
开发语言·c++
Jelena157795857921 小时前
爬虫与翻译API接口的完美结合:开启跨语言数据处理新纪元
开发语言·数据库·爬虫
柠石榴1 小时前
【练习】【二叉树】力扣热题100 102. 二叉树的层序遍历
c++·算法·leetcode·二叉树
gyc27271 小时前
快速熟悉JavaScript
开发语言·前端·javascript
越甲八千1 小时前
C++海康相机DEMO
开发语言·c++·数码相机