使用operator[]时如何区分读/写操作

2024-03-04

我需要编写一个带有重载运算符 [] 的类,当使用运算符 [] 读取或写入数据时,该类具有不同的行为。 为了给出我想要实现的目标的实际示例,假设我必须编写一个名为 PhoneBook 的类的实现,该类可以按以下方式使用:

PhoneBook phoneBook(999999); // 999999 is the default number which should be
                             // used when calling someone who is not in the phone book

phoneBook["Paul"] = 234657;  // adds Paul's number
phoneBook["John"] = 340156;  // adds John's number

// next line should print Paul's number 234657
cout << "To call Paul dial " << phoneBook["Paul"] << endl;
// next line should print John's number 340156
cout << "To call John dial " << phoneBook["John"] << endl;
// next line should print 999999 because Frank is not in the phone book
cout << "To call Frank dial " << phoneBook["Frank"] << endl;

问题在于,当使用时

phoneBook["Frank"]

我不想在电话簿中添加 Frank 的条目,否则基于 std::map 的解决方案将很容易实现。

我在网上没有找到任何标准方法来实现这一目标,所以 经过一番思考,我想出了以下解决方案,其中运算符 [] 返回一个名为 PhoneNumber 的“临时对象”。然后使用 PhoneNumber 来区分读/写操作:

#include <iostream>
#include <string>
#include <map>

using namespace std;

class PhoneBook{
private:
    map<string, int> data_; // stores phone numbers
    int defaultNumber_; // default number returned when no matching name is found

public:
    PhoneBook(int defaultNumber) :
        defaultNumber_(defaultNumber) {}

    // Searches in the phone book for a name. If the name is found it returns
    // the corresponding number. If the name is not found it returns defaultNumber_
    int read(string name){
        map<string, int>::iterator it = data_.find(name);
        if (it==data_.end()){
            return defaultNumber_;
        } else {
            return it->second;
        }
    }

    // Forwarding function to map operator []. It is not really necessary but it is added for clarity
    int& write(string name){
        return data_[name];
    }

    // Forward declaration of the "temporary object" returned by operator []
    // See declaration below
    class PhoneNumber;

    PhoneNumber operator[](string name){
        return PhoneNumber(this, name);
    }

    class PhoneNumber{
        friend class PhoneBook;
    private:
        PhoneBook* const phoneBook_;
        string name_;

        // Constructors are private so that PhoneNumber can be used only by PhoneBook
        // Default constructor should not be used
        PhoneNumber() :
            phoneBook_(NULL) {}

        PhoneNumber(PhoneBook* phoneBook, string name) :
            phoneBook_(phoneBook), name_(name) {}

    public:
        // conversion to int for read operations
        operator int (){
            return phoneBook_->read(name_);
            }

        // assignment operator for write operations
        const int& operator = (const int& val){
            return phoneBook_->write(name_) = val;
        }
    };
};

int main(){
    PhoneBook phoneBook(999999);

    phoneBook["Paul"] = 234657;
    phoneBook["John"] = 340156;

    cout << "To call Paul dial " << phoneBook["Paul"] << endl;
    cout << "To call John dial " << phoneBook["John"] << endl;
    cout << "To call Frank dial " << phoneBook["Frank"] << endl;

    return 0;
}

PhoneBook 类的行为就像我想要的那样,程序打印:

To call Paul dial 234657
To call John dial 340156
To call Frank dial 999999

我想问你一些问题:

  1. 有没有更好的方法来获得一个行为类似于我编码的类的类?
  2. 我正在使用的技术是否有一个名称,以便我可以搜索有关它的更多信息?
  3. 您认为我的解决方案有任何缺点/可能的改进吗?

在我正在编写的库中,启用我为 PhoneBook::operator[] 获得的行为 在类似的情况下非常重要,我真的很想知道您对我的问题的看法。

Thanks!


您提出的是这个问题的标准解决方案。通常是 称为代理模式或代理习惯用法,以及您所使用的帮助器类 return 称为代理。 (由于它是一个嵌套类,只需调用 它Proxy一般情况下就足够了。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用operator[]时如何区分读/写操作 的相关文章

随机推荐

  • Fusion Table 和 Google 服务帐户

    我正在尝试使用 Google 服务帐户从我的 AppENGine Java 应用程序访问 Fusion 表 此代码片段用于获取 OAuth 访问令牌 ArrayList
  • 通过交替行组进行 SQL 分区

    我有一个类似这样的数据表 Key LotId TransactionType Quantity Destination 1 A Transform NULL Foo 2 A Transform NULL Bar 3 A Consume 10
  • 从 PHP 执行 Perl 脚本时出现问题

    试图弄清楚这一点 我正在尝试使用 shell exec 在 php 中执行 perl 脚本 如下所示 它不会使用 gt filename txt 将输出写入文件 如果我执行而不将其定向到文件名 它将起作用 因为我可以使用 echo 确认这一
  • Spring MVC:在 中使用通配符

    我正在为 Spring MVC 应用程序实现一个缓存清除系统 为了让这个系统正常工作 我必须从给定的 URL 中删除 缓存清除代码 假设我生成的缓存清除代码是 123 并且我有一个 css 网址 public 123 css style c
  • 如何从 C# 调用 C++ dll 导出函数

    这是我第一次尝试将 C 与非托管 C 混合在一起 所以这可能是一个非常简单的问题 但我不明白 我需要将 C dll 中的一些函数调用到 C 代码中 以下是 dll 项目的代码 h 文件 pragma once include
  • D的语法真的是上下文无关的吗?

    几个月前我在 D 新闻组上发布了这个问题 但由于某种原因 答案从未真正说服我 所以我想我应该在这里问 D 的语法显然是上下文无关的 http www digitalmars com d 2 0 template comparison htm
  • 将值分配给 R 中数组的特定维度

    我有一个多维数组并尝试将值分配给特定维度 请参阅下面的代码了解我当前的方法 Create a array and fill with NA set seed 1 dim arr lt seq 2 10 arr lt array NA dim
  • Angular 5子路由在路由中添加括号

    我有一个带有一系列组件的 Angular 5 应用程序 有些组件是其他组件的子组件 有些则不是 我希望应用程序具有如下结构 my account overview homepage my account my stuff profile n
  • 在开发过程中我应该如何将 Perl 警告升级为致命错误?

    当运行应用程序测试套件时 我想将所有 Perl 编译和运行时警告 例如 未初始化的变量 警告 升级为致命错误 以便我和其他开发人员调查并修复生成警告的代码 但我只想在开发和 CI 测试期间这样做 在生产中 警告应该只是警告 我尝试了以下操作
  • homestead.rb:109:in `read': 没有这样的文件或目录@ rb_sysopen

    我尝试通过官网的文档5 3使用homesteadhttps laravel com docs 5 3 homestead https laravel com docs 5 3 homestead但它不起作用 详细信息如下 C Users l
  • Cypress.io 中选择器的存储位置

    我是赛普拉斯的新手 避免将选择器 定位器硬编码到每个规范中的最佳方法是什么 在其他框架中 我们将创建一个包含所有选择器的配置文件 并让规范引用它 场景 我可能有一个在多个规范中使用的选择器 如果选择器发生变化 我不想在每个规范中更改它 我宁
  • 添加到多个 std 容器时 C++ 中的异常安全

    我有一些代码添加到std vector and a std map创建对象后 v push back object std vector m object gt id object std map 我想让这个有一个强有力的例外保证 通常 为
  • 与php中的另一个数组合并后如何从数组中删除重复元素?

    我正在尝试编写程序来计算指定开始日期后的接下来 20 个日期 然后从 20 个日期中排除周末 Holidays Array holidays 2016 12 13 2016 12 24 以及结果数组 其中仅包含除周六和周日之外的工作日 在假
  • Keycloak,如果选择更新密码操作,则不返回访问令牌

    我正在打电话 auth realms master protocol openid connect token通过在正文中发送以下内容来获取访问令牌 grant type password client id example docker
  • 如何使用 JavaScript 在 Hackerrank 中发出 AJAX 请求?

    我打开 Hackerrank 示例测试并尝试使用可能用于进行 AJAX 调用的方法 XMLHttpReq fetch等等 它们都不起作用 XHR and fetch方法不可用 First fetch async function myFet
  • 维纳滤波

    我想编写一个维纳滤波器来改善图像 我不想使用傅立叶 我知道有一个基于中值和方差的算法 但我找不到它 你们能帮我吗 http en wikipedia org wiki Wiener filter http en wikipedia org
  • 如何为新样式表生成 CSS 变量值

    我正在开发一个项目 用户可以从颜色输入中选择颜色 并使用 CSS 变量动态创建自己的主题 我希望用户能够下载包含他们选择的值的整个 CSS 文件 My issue 下载的CSS文件不显示实际的颜色值 而是显示变量名称 NOT WANTED
  • Python:CGI在脚本退出前更新网页

    好吧 这是我的情况 我编写了一个带有文本区域的 HTML 表单 该文本区域向我的 python 脚本提交 POST 请求 我使用 cgi 库来解析文本区域并将其拆分为一个数组 然后 我使用循环处理这些项目并在处理时打印它们 看来 即使我将打
  • JavaScript 和 Java 有什么区别?

    Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 JavaScript 和 Java 有什么区别 Java 和 Javascript 很相似 就
  • 使用operator[]时如何区分读/写操作

    我需要编写一个带有重载运算符 的类 当使用运算符 读取或写入数据时 该类具有不同的行为 为了给出我想要实现的目标的实际示例 假设我必须编写一个名为 PhoneBook 的类的实现 该类可以按以下方式使用 PhoneBook phoneBoo