C++11备忘录模式展示

2021-07-16  本文已影响0人  FredricZhu

题目,


image.png

这个题目看上去很长,其实很简单,就是在添加Token对象的时候,需要返回Tokens对象的一个副本。
因为vector<shared_ptr<Token>>中存储的都是智能指针,所以不能直接auto ret_tokens {tokens},这样虽然拷贝出了相应vector对象的一个副本,但是副本中存储的仍让是智能指针,智能指针中raw pointer指向的地址仍然是同一份值。这是由智能指针的引用计数特性决定的。
我这里的方法特别傻,也很低效。
就是直接一个一个创建新的Token,放到返回的vector中。
为避免ret_tokens做二次拷贝影响性能,这里给Memento对象实现了一个右值的构造函数,然后做了两次std::move操作。
代码如下,

#include <iostream>
#include <vector>
#include <memory>
using namespace std;

struct Token
{
  int value;

  Token(int value) : value(value) {}
};

struct Memento
{   
    Memento(vector<shared_ptr<Token>>&& tokens_): tokens{std::move(tokens_)} {
        cout << "Move version of vector constructor is invoked..." << endl;    
    }
    
    Memento(const vector<shared_ptr<Token>>& tokens_): tokens{tokens_} {}
    vector<shared_ptr<Token>> tokens;
};

struct TokenMachine
{

  vector<shared_ptr<Token>> tokens;

  Memento add_token(int value)
  {
    return add_token(make_shared<Token>(value));
  }

  // adds the token to the set of tokens and returns the
  // snapshot of the entire system
  Memento add_token(const shared_ptr<Token>& token)
  {
      // Add Token to the set of tokens
      tokens.push_back(token);
      
      // Return snapshot of the entire system
      vector<shared_ptr<Token>> ret_tokens;
      for(auto&& tmp_token: tokens) {   
          ret_tokens.push_back(make_shared<Token>(tmp_token->value));
      }
      return {std::move(ret_tokens)};
  }

  // reverts the system to a state represented by the token
  void revert(const Memento& m)
  {
      tokens = m.tokens;
  }
};

int main(int argc, char* argv[]) {
    TokenMachine tm;
    tm.add_token(1);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读