RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1436983
Accepted
podpivas
podpivas
Asked:2022-09-07 05:51:58 +0000 UTC2022-09-07 05:51:58 +0000 UTC 2022-09-07 05:51:58 +0000 UTC

我无法捕捉触发重载赋值运算符的时刻,以及可以优化的内容

  • 772
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <Windows.h>
#include <map>
using namespace std;
class String {
private:
    unsigned int length;
    char* cstring;
  
    void clean() {
        if (cstring) {
            delete[] cstring;
        }
        length = 0;
    }
public:    
    String(const char* str) : length(strlen(str)),  cstring(new char[length + 1]) {
        strcpy(cstring, str);
        cout << "ctor" << endl;
    }
    String() : String("") {

    }
    String(int size, char symbol) : cstring(new char[size + 1]), length(size) {
        if (size) {
            memset(cstring, symbol, size);
            cstring[size] = '\0';
        }
    }
    String(const String& other) {
        length = other.length;
        cstring = new char[length + 1];
        strcpy(cstring, other.cstring);
    }
    String& operator=(const String& other) {
        cout << "String& operator=(const String& other)" << endl;
        if (this == &other)
            return *this;
        clean();
        length = other.length;
        cstring = new char[length + 1];
        strcpy(cstring, other.cstring);
        return *this;
    }
    String(String&& other) noexcept {
        length = other.length;
        cstring = other.cstring;      
        other.cstring = nullptr;
    }
    String& operator=(String&& other) noexcept {
        cout << "=&&" << endl;
        if (this == &other)
            return *this;
        
        clean();
        length = other.length;
        cstring = other.cstring;
        other.cstring = nullptr;
        return *this;
    }
    String& operator +=(String const& other) {
        cout << "=+" << endl;
        if (other.length) {
            unsigned int size = length + other.length;
            char* buff = new char[size + 1];
            strcpy(buff, cstring);
            strcat(buff, other.cstring);
            clean();
            cstring = buff;
            length = size;
            buff = nullptr;
            return *this;
        }
    }
    ~String() { 
        clean();
        cout << "dtor" << endl;
    }

    inline bool isEmpty() { return length == 0; }
    inline unsigned int getLength() { return length; }
    inline const char* c_str() const { return cstring; }
    bool operator==(const String& t) const {
        return length == t.length && strcmp(cstring, t.cstring) == 0;
    }
    bool operator !=(const String& t) const {
        return !(operator==(t));
    }
    char& operator[](const int i) {
        return cstring[i];
    }
    void stringLow() {
        for (int j = 0; j < length; ++j)
            cstring[j] = (char)(tolower(cstring[j]));
    }
    void stringUp() {
        for (int j = 0; j < length; ++j)
            cstring[j] = (char)(toupper(cstring[j]));
    }
    void reverse() {
        for (int i = 0; i < length / 2; i++) {
            swap(cstring[i], cstring[length - i - 1]);
        }
    }
    friend String operator+(String l, const String& r) {
        return l += r;
    }
    friend istream& operator >>(istream& is, String& obj) {
        char* buff = new char[99];
        memset(&buff[0], 0, sizeof(buff));
        is >> buff;
        obj = String(buff);
        delete[] buff;
        return is;
    }
    friend ostream& operator <<(ostream& os, const String& obj) {
        os << obj.cstring;
        return os;
    }
};

int main() {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    String var("Люблю ");
    String var2("много пива");
    String var3 = var + var2;    
}
c++
  • 1 1 个回答
  • 32 Views

1 个回答

  • Voted
  1. Best Answer
    Harry
    2022-09-07T13:56:21Z2022-09-07T13:56:21Z

    好吧,我会做这样的事情......

    #include <cstring>
    #include <iostream>
    
    class String
    {
    private:
        size_t length;
        char* cstring;
      
        void swap(String& s)
        {
            std::swap(cstring,s.cstring);
            std::swap(length,s.length);
        }
    public:    
        String(const char* str = "")
            : length(str ? strlen(str) : 0)
            , cstring(new char[length + 1])
        {
            strcpy(cstring, str ? str : "");
        }
    
        String(size_t size, char symbol)
            : length(size)
            , cstring(new char[size + 1])
        {
            memset(cstring, symbol, size);
            cstring[size] = '\0';
        }
    
        String(const String& other):String(other.cstring) {}
    
        String& operator=(const String& other)
        {
            if (this != &other)
            {
                String tmp(other);
                swap(tmp);
            }
            return *this;
        }
    
        String(String&& other) noexcept
            : length(other.length)
            , cstring(other.cstring)
        {
            other.length  = 0;
            // Вообще-то после move должно оставаться
            // СОГЛАСОВАННОЕ состояние, но у вас
            // нулевая длина означает пустую строку.
            // Возможно, стоит переписать эту строку
            // соответствующим образом:
            other.cstring = nullptr;
        }
    
        String& operator = (String&& other) noexcept
        {
            if (this != &other) swap(other);
            return *this;
        }
    
        String& operator +=(String const& other)
        {
            if (other.length) {
                size_t size = length + other.length;
                char* buff = new char[size + 1];
                strcpy(buff, cstring);
                strcat(buff, other.cstring);
                delete[] cstring;
                cstring = buff;
                length  = size;
            }
            return *this;
        }
    
        ~String()
        {
            delete[] cstring;
        }
    
        bool        isEmpty()   const { return length == 0; }
        size_t      getLength() const { return length; }
        const char* c_str()     const { return cstring; }
    
        bool operator==(const String& t) const noexcept
        {
            return length == t.length && strcmp(cstring, t.cstring) == 0;
        }
        bool operator !=(const String& t) const noexcept
        {
            return !(*this == t);
        }
    
        char& operator[](size_t i)  // Без проверок?
        {
            return cstring[i];
        }
    
        String& Lo() {
            for (int j = 0; j < length; ++j)
                cstring[j] = (char)(tolower(cstring[j]));
            return *this;
        }
    
        String& Up() {
            for (int j = 0; j < length; ++j)
                cstring[j] = (char)(toupper(cstring[j]));
            return *this;
        }
    
        String& reverse() {
            for (size_t i = 0, j = length-1; i < j; ++i, --j) {
                std::swap(cstring[i], cstring[j]);
            }
        }
    
        friend String operator+(const String& l, const String& r)
        {
            String t(l);
            return t += r;
        }
    
        friend std::istream& operator >>(std::istream& is, String& obj)
        {
            // Оставляю на вашей совести невозможность чтения длинных слов
            char* buff = new char[99];
            memset(&buff[0], 0, sizeof(buff));
            // Это в современном С++ не компилируемо:
            is >> buff;
            obj = String(buff);
            delete[] buff;
            return is;
        }
    
        friend std::ostream& operator <<(std::ostream& os, const String& obj) {
            os << obj.cstring;
            return os;
        }
    };
    
    using namespace std;
    
    int main() {
        //SetConsoleCP(1251);
        //SetConsoleOutputCP(1251);
        String var("Люблю ");
        String var2("много пива");
        String var3;
        var3 = var + var2;   // Теперь тут есть присваивание
        cout << var << endl;
        cout << var2 << endl;
        cout << var3 << endl;
    }
    

    主要是明确定义类不变量。然后零长度可以对应空字符串和nullptr. 长度本身仅对足够大的字符串长度有意义,否则它不会进行太多优化。

    不需要相同的clean(),因为在类中不需要将长度归零的情况下调用它。是的,它delete可以与 一起使用nullptr,不需要检查。

    一般来说,如果不清楚为什么我做错了什么,看看是什么以及如何做 - 问。

    是的,以防万一:不要意外更改数据成员的声明顺序,您的构造函数依赖它。还有一件事——在声明一个类时,你不应该使用using namespace,把它留给用户。在一个类中,最好使用完全限定名。

    • 3

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5