首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++ Practical-2 day2 运算符重载之时钟类++运算符

  • 25-02-19 07:41
  • 2632
  • 13989
blog.csdn.net

系列文章目录

点击直达——文章总目录


文章目录

  • 系列文章目录
  • C++ Practical-2 day2 运算符重载之时钟类++运算符
    • Overview
    • 1.时间类 重载后缀`++`运算符来递增时间
      • 1.1.解释
      • 1.2.注意事项
    • 2.如何确保时间递增操作在多线程环境中是线程安全的?
    • 关于作者


C++ Practical-2 day2 运算符重载之时钟类++运算符

Overview

  • C++不练习coding,就相当于空中楼阁,基础不扎实
  • 光吃不干,等于没吃
  • clock_overloading

1.时间类 重载后缀++运算符来递增时间

在C++中创建一个时钟类并重载函数调用运算符(),可以使得该类的实例可以像函数一样被调用,以执行特定的操作,比如获取当前时间、设置时间等。

下面是一个简单的示例,展示如何定义一个时钟类,该类重载了函数调用运算符来获取当前时间:

为了实现通过重载后缀++运算符来递增时间,我们需要在Clock类中添加一个特殊的成员函数。这个成员函数将实现后缀递增操作。

#include 
#include 

class Clock {
private:
    time_t currentTime;

public:
    // 构造函数
    Clock() {
        currentTime = time(0); // 初始化为当前时间
    }

    // 重载()运算符,返回当前时间的字符串表示
    std::string operator()() const { // 保持const
        tm *ltm = localtime(&currentTime); // 转换为本地时间
        char buffer[80];
        strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", ltm); // 格式化时间
        return std::string(buffer);
    }

    // 设置时间
    void setTime(time_t newTime) {
        currentTime = newTime;
    }

    // 获取时间
    time_t getTime() const {
        return currentTime;
    }

    // 计算两个时间点之间的差异(秒)
    double timeDifference(const Clock &other) const {
        return difftime(other.currentTime, currentTime);
    }

    // 时间递增
    void incrementTime(int seconds) {
        currentTime += seconds;
    }

    // 重载前置++运算符
    Clock& operator++() {
        incrementTime(1); // 递增1秒
        return *this;
    }

    // 重载后置++运算符
    Clock operator++(int) {
        Clock temp = *this; // 保存当前状态
        incrementTime(1);   // 递增1秒
        return temp;       // 返回递增前的状态
    }
};

int main() {
    Clock myClock;
    std::cout << "Current time: " << myClock() << std::endl;

    // 手动设置时间
    myClock.setTime(time(0)); // 重新设置为当前时间
    std::cout << "Current time after setting: " << myClock() << std::endl;

    // 创建另一个时钟实例
    Clock anotherClock;
    anotherClock.setTime(time(0) + 3600); // 设置为当前时间1小时后

    // 计算两个时间点之间的差异
    double diff = myClock.timeDifference(anotherClock);
    std::cout << "Time difference: " << diff << " seconds" << std::endl;

    // 使用后置++运算符递增时间
    myClock++;
    std::cout << "Current time after incrementing: " << myClock() << std::endl;

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

1.1.解释

  1. 重载后缀++运算符:

    • 功能:实现后缀递增操作,即每次调用myClock++时,currentTime递增1秒。
    • 返回值:返回Clock对象的引用,允许链式调用。
  2. main函数:

    • 创建Clock类的实例myClock。
    • 使用重载的()运算符获取并打印当前时间。
    • 手动设置时间,并再次打印当前时间。
    • 计算两个时间点之间的差异,并打印结果。
    • 使用后缀++运算符递增时间,并打印递增后的时间。
  3. Clock类:

    • 私有成员变量:currentTime,用于存储时间。
    • 构造函数:初始化currentTime为当前时间。
    • 重载的()运算符:返回当前时间的字符串表示。它使用time()函数获取当前时间,然后使用localtime()将其转换为本地时间,最后使用strftime()格式化时间字符串。
    • setTime成员函数:允许设置时间。
    • getTime成员函数:返回当前时间。

通过这种方式,Clock类现在可以通过重载后缀++运算符来递增时间,使得代码更加简洁和直观。

1.2.注意事项

  1. const修饰符:如果你的重载的()运算符不会修改对象的状态,你应该在函数声明的末尾添加const关键字,以表明这个成员函数不会修改对象的任何成员变量。

  2. 参数:你可以为()运算符提供参数,比如设置时间。

  3. 返回类型:你需要指定函数调用的返回类型。

通过这种方式,你可以创建一个非常灵活的时钟类,该类的对象可以像函数一样被调用,以执行特定的操作。

2.如何确保时间递增操作在多线程环境中是线程安全的?

为了确保时间递增操作在多线程环境中是线程安全的,我们需要确保当多个线程尝试同时修改时间时,这些修改不会相互干扰,导致数据不一致。这通常涉及到使用同步机制,如互斥锁(mutexes),来保护对共享资源的访问。

以下是一些确保线程安全的方法:

  1. 使用互斥锁(Mutex):
    在C++中,可以使用std::mutex来确保只有一个线程可以同时修改时间。在递增时间的函数中,我们需要在修改时间之前获取锁,并在修改后释放锁。

     #include 
     #include 
     #include 
    
     class Clock {
     private:
         time_t currentTime;
         mutable std::mutex mtx; // 使用mutable因为mtx在const成员函数中使用
    
     public:
         Clock() {
             currentTime = time(0);
         }
    
         // 重载()运算符
         std::string operator()() const {
             std::lock_guard<std::mutex> lock(mtx); // 使用lock_guard自动加锁和解锁
             tm  *ltm = localtime(&currentTime);
             char buffer[80];
             strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", ltm);
             return std::string(buffer);
         }
    
         // 线程安全的时间递增
         void incrementTime(int seconds) {
             std::lock_guard<std::mutex> lock(mtx);
             currentTime += seconds;
         }
    
         // 重载后缀++运算符
         Clock &operator++() {
             incrementTime(1);
             return *this;
         }
     };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  2. 使用原子操作:
    如果时间递增操作可以被设计为原子操作,那么可以使用std::atomic来确保操作的原子性。

    #include 
    #include 
    
    class Clock {
    private:
        std::atomic<time_t> currentTime;
    
    public:
        Clock() {
            currentTime.store(time(0));
        }
    
        void incrementTime(int seconds) {
            currentTime.fetch_add(seconds, std::memory_order_relaxed);
        }
    
        Clock& operator++() {
            incrementTime(1);
            return *this;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  3. 使用条件变量:
    如果需要更复杂的线程间协调,可以使用std::condition_variable来等待和通知时间变化。

  4. 避免共享:
    如果可能,避免共享时间对象,每个线程可以使用本地时间副本,然后定期同步。

  5. 使用线程安全的类:
    使用标准库中已经保证线程安全的类,如std::chrono中的一些类。

确保线程安全通常需要仔细设计,并且在多线程程序中进行充分的测试,以确保没有死锁或竞态条件。


关于作者

  • 微信公众号:WeSiGJ
  • GitHub:https://github.com/wesigj/cplusplusboys
  • CSDN:https://blog.csdn.net/wesigj
  • 微博:
  • -版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
WeSiGJ
微信公众号
共同分享,共同交流, 共同学习!
注:本文转载自blog.csdn.net的WeSiGJ的文章"https://blog.csdn.net/wesigj/article/details/142603004"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top