gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 17:52:20 26 4
gpt4 key购买 nike

我需要编写一个带有重载运算符 [] 的类,当使用运算符 [] 读取或写入数据时,它具有不同的行为。举一个我想要实现的实际例子,假设我必须编写一个名为 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[] 获得的行为在类似的情况下真的很重要,我真的很想知道你对我的问题的看法。

谢谢!

最佳答案

您提出的是该问题的标准解决方案。通常是被称为代理模式或代理习语,以及你的助手类返回称为代理。 (因为它是一个嵌套类,只需调用Proxy 通常就足够了。)

关于c++ - 使用operator[]时如何区分读/写操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9330815/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com