这是参考类成员的习惯用法吗?

时间:2014-06-13 08:26:23

标签: c++

我有以下类定义:

class Policy {
public:
    virtual DigraphNode getBestMove(DigraphNode &node) const = 0;
};

class NoPolicy : public Policy{
    virtual DigraphNode getBestMove(DigraphNode &node) const 
       {return DigraphNode();}
};

class Agent {
public:
    static NoPolicy noPolicy;
    Agent() : policy(noPolicy) {}
    void setPolicy(Policy &p) {policy = p;}
    Policy &getPolicy() {return policy;}
private:
    Policy &policy; // pointer so polymorphism should work
};

Agent :: policy可以存储任何后代Policy类的对象。为避免使用指针,我将此成员作为参考。但是,我需要在构造函数中初始化它,这迫使我按照您在代码中看到的那样定义一个人为策略NoPolicy。这有效,但似乎有点人为。

为了完成图片,我最终在客户端代码中使用了以下用法:

Policy &policy = Agent::noPolicy;
switch(agentTypes[a]) {
case NON_COMPLIANT:
    policy = HeuristicBasedPolicy<MultiHeuristic>(nearExitH);
    break;
    etc.

如果有人能提出更优雅的方式,我将非常感激。谢谢!

备注:代码中的评论已过时。 Agent :: policy是一个引用,当然不是指针。

-----------------------编辑(根据反馈)---------------- ------------------

根据我得到的反馈(谢谢!),我修改了代码。类定义是:

class Policy {
public:
    virtual DigraphNode getBestMove(DigraphNode &node) const = 0;
};

class Agent {
public:
    Agent() {policy = nullptr;}
    void setPolicy(Policy *p) {policy = p;}
    Policy &getPolicy() {return *policy;}
private:
    Policy *policy; // pointer so polimorphism should work
};

用法是:

vector<Policy *> agentPolicies; // need this only to free memory!
while (node->getDepth()) {
   int a = node->getDepth() - 1;
   Policy *myPolicy;
   switch(agentTypes[a]) {
   case NON_COMPLIANT:
     myPolicy = new HeuristicBasedPolicy<MultiHeuristic>(nearExitH);
     break;
   ...
   }
   agents[a].setPolicy(myPolicy);
   agentPolicies.push_back(myPolicy);
}
...
for (int i = 0; i < agentPolicies.size(); i++)
   delete(agentPolicies[i]);

如果这是评论和回复的人的意图,请告诉我。

此外,客户端代码第一行中的数组仅用于保留指针以便稍后释放它们。这是一个正常的事态,只有内存管理的簿记有一个数组?谢谢!

1 个答案:

答案 0 :(得分:1)

正如您所见,该引用存在必须存在的问题 在构造函数中设置。然后永远不会改变。如果这 是你想要的,这个课不应该是可分配的 (那可能是Agent)的情况 引用是有效的解决方案。如果班级需要 可分配,或者您可能需要更改策略 构造,然后指针是通常的解决方案。

更一般地说,我看过禁止的编码指南 参考成员,因为他们无法做到 对象可分配。就个人而言,我不同意他们,因为 很多课程都有身份,不应该支持复制和 分配。但它可能相当惯用 系统地使用指针作为类成员,即使在 参考可行。

话虽如此:使用无操作类也是相当惯用的 在这种情况下。使类不变通常更容易 policy != nullptr,而只是做policy->something() 而不是必须在整个地方检查nullptr。 (你可以 但是,仍然需要指针,因为您可能想要更改 该政策,特别是如果它是NullPolicy之后的政策 对象已经构建。)如果你这样做,你可以(和 可能应该有getPolicy之类的函数返回 参考,像setPolicy这样的函数可以作为参考。

此外,像Policy这样的类可能是不可变的(特别是 如果你共享它们的实例),那么你应该使用指针 to const和对const的引用。

最后:为什么你想避免使用指针?好 编写C ++,至少面向对象的C ++,将充满 指针。