我有以下代码:
class Game {
private:
const Ruleset& rules;
public:
Game(const Ruleset&);
}
public class Ruleset {
public:
virtual ~Ruleset();
virtual bool isMoveValid(Move&) const = 0;
}
现在,以下initilializer工作正常:
Game::Game(const Ruleset& r) : rules(r) {}
但我发现这并没有保护我免受悬挂对临时工的引用。我想到了以下解决方案:
class Game {
private:
const Ruleset& rules;
public:
Game(const Ruleset&);
Game(const Ruleset&&) = delete;
}
这段代码的问题在于我在游戏中有很多构造函数的变体,我希望避免删除其他每一个,所以我想要像
这样的东西class Game {
private:
const Ruleset rules;
public:
Game(const Ruleset&&);
}
Game::Game(const Ruleset& r) : rules(forward(r)) {}
可能有更多复制/移动的参数。假设我有一个带有4个参数的构造函数:
Constructor(type1&, type2&, type3&, type4&).
然后我想在可能的情况下使用move-constructor,但我不想编码Constructor的每个变体(type1&&,type2&,type3&,type4&)等......
这可能吗? (当然,Ruleset类必须现在声明移动构造函数)。当你有一个更好的解决问题的方法时,也要指出,这有助于我有效地编写这个类。
答案 0 :(得分:1)
如果你只想接受左值,你可以写一个这样做的构造函数:
Game(RuleSet& r)
: rules(r)
{ }
这样你就不能轻易传递临时状态了,你仍然可以const&
接受传递的内容。
您也可以通过通用引用获取每个参数并逐个转发每个参数。这也会隐藏const
方面并强制您的rules
成员成为const RulesSet*
而不是参考:
template <typename Arg1, typename Arg2>
Game(Arg1&& a1, Arg2&& a2)
{
initRulesSet(std::forward<Arg1>(a1));
initSomethingElse(std::forward<Arg2>(a2));
}
void initRulesSet(RulesSet&& ) = delete;
void initRulesSet(const RulesSet& rs) { rules = &rs; }