Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是引用类成员的惯用用法吗?_C++ - Fatal编程技术网

C++ 这是引用类成员的惯用用法吗?

C++ 这是引用类成员的惯用用法吗?,c++,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

我有以下类定义:

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
};

代理::策略可以存储策略的任何子类的对象。为了避免使用指针,我将这个成员作为引用。然而,然后我需要在构造函数中初始化它,这迫使我定义一个人工策略NoPolicy,正如您在代码中看到的那样。这是可行的,但似乎有点做作

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

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

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]);
向量代理政策;//只需要这个来释放内存!
同时(节点->获取深度(){
int a=node->getDepth()-1;
政策*我的政策;
开关(代理类型[a]){
不符合要求的情况:
myPolicy=基于启发式的新策略(nearExitH);
打破
...
}
代理[a].setPolicy(myPolicy);
代理政策。推回(我的政策);
}
...
对于(int i=0;i
请让我知道这是否是评论和回复的人的意图


此外,客户机代码第一行中的数组仅用于保留指针,以便以后发布它们。仅仅为了内存管理的簿记而拥有一个数组,这是一种正常的情况吗?谢谢

正如您所看到的,引用有一个问题,它必须是 在构造函数中设置。那是永远无法改变的。如果这 是您想要的,并且类不应该是可分配的 (可能是被称为
代理的情况),然后
引用是有效的解决方案。如果需要的话
可分配,或者您可能需要在策略被分配后更改策略
构造,则指针是通常的解决方案

更一般地说,我见过一些编码准则禁止 参考成员,因为他们使 对象可分配。就个人而言,我不同意他们,因为 很多类都有标识,不应该支持复制和复制 分配但这可能是相当惯用的 系统地使用指针作为类成员,即使在 推荐信就行了

话虽如此:使用无操作类也是相当惯用的 在这种情况下。拥有一个类不变量通常更容易
策略!=nullptr
,只需执行
策略->某事()
,而不是 而不是到处检查
nullptr
。(你可以 但是,仍然需要指针,因为您可能需要更改 在 如果您这样做,您可以(和 可能应该)具有类似于
getPolicy
return的函数 一个引用,像
setPolicy
这样的函数获取一个引用

另外,像
Policy
这样的类可能是不可变的(尤其是 如果共享它们的实例),那么应该使用指针 到const和对const的引用

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

“为了避免使用指针,我将此成员作为参考”。避开指针不是目标,而是实现目标的一种手段。你想达到什么目标?“这很有效”。真正地调用
setPolicy
时会发生什么?指针需要分配和销毁,并且需要有人拥有它们。我想避免思考这些问题的痛苦。另外,我不想通过使用共享指针来增加编译时间。对不起,我说的“作品”是指“通过编辑”。我还没有机会运行代码,因为我仍在与编译器争论其他问题。引用只设置一次(在初始化时),不能重新绑定到其他变量。你的意思是编译器应该为我的Agent::setPolicy()代码对我大喊大叫,我真的应该回去使用指针吗?“指针需要分配和销毁,需要有人拥有它们。“你完全错了,在犯更大的错误之前,你需要尽快修复它。对象需要分配和销毁,需要有人拥有它们。指针是指对象的东西。参考文献也是如此。它们的工作方式有点不同,但差异并没有那么重要。
std::reference\u wrapper
可能是一个可行的解决方案。我用一个修改过的代码编辑了我的文章,该代码使用了指针类成员(我确实需要能够在初始实例化之后多次修改代理的策略;感谢大家纠正我的错误!)我仍然对编辑中显示的代码不是100%满意,并希望得到进一步的评论。谢谢!具有引用成员的对象无法分配这一事实并不是避免引用成员的唯一原因。更重要的原因是,您看不到使用引用的代码中发生了什么。这可能会起作用这隐藏了对象之间的连接,这是bug滋生的沃土。就我个人而言,我将引用的使用限制为常量引用作为函数参数(这只是对传递值语义的优化).@Chnossos什么问题的解决方案?@cmaster我看不到你那么黑暗,但我确实看到了你的意图。实际上,当我想提供对内部数据的访问时,我只会将引用用作函数的参数和返回值(例如std::vector::operator[]`)。
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]);