题目,
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;
}
网友评论