将一个类绑定到另一个类

时间:2014-06-19 08:04:01

标签: c++ pointers c++11 constraints

假设我有一个定义特定问题的类,例如,获取某个函数的值。但是这个函数只能采用特定的参数,即它们偏向某些约束。这是一个简单的例子:

class Problem
{
private:
   std::function<double(const std::vector<double>&)> d_func;
   std::vector<std::pair<double,double>> d_constraints;
public:
   double evaluate(const std::vector<double>& args)
   {
       return d_func(args);
   }
   bool isWithinDomain(const std::vector<double>& args) 
   {
       /*check whether args is in the domain defined with d_constraints*/
   }
};

还有另一个类解决方案,它包含一个可以传递给Problem中定义的函数的参数以及该函数的值:

class Solution
{
private:
   std::vector<double> d_solution;
   double d_value;
};

我可以有很多可能的Solution,但它们都有相同的边界和功能可以传递。所以我的问题是:将Problem的信息合并到Solution的最佳方式是什么?一种解决方案是在Problem内有一个指向Solution的指针,因此如果在Problem中更改了约束或函数,我们在每个Solution中都有更新版本的{{1}}实例。 但是,自从c ++ 11以来,它不推荐使用原始指针,所以我可能需要使用shared_ptr,但是它们存在性能问题......

任何帮助都将受到高度赞赏!

2 个答案:

答案 0 :(得分:3)

  1. 原始指针(永远不会)弃用。 拥有原始指针已被弃用(或实际上不鼓励使用)。如果你有其他人拥有Problem个实例,那么在Solution内有一个指向它们的原始指针就可以了。当然,您必须确保Solution没有Problem更长。

  2. 但是,如果您希望Solution拥有Problem个对象,则应该转向共享所有权。您提到std::shared_ptr存在性能问题 - 您究竟是什么意思?是的,复制或销毁shared_ptr需要原子操作,但解除引用则不需要。您是否进行过任何分析以确定它是否会成为实际问题?

    永远不要根据感觉效率太低的情况做出重要的设计决策。始终先测量。

答案 1 :(得分:1)

由于Problem不拥有Solution对象,因此在Solution实例中指向相对Problem的正常C指针是可以的。试图解决。

确保您的Problem对象生命周期比您的Solution生命周期长。

如果您的Solution个对象之一可以在多个Problem之间共享(也很有意义),那么您可能希望使用 factory(伪代码)

class Solution {
    public:
};

class Problem : public Registry /*creation-time registration? Your question doesn't mention that*/ {
    public:
};

// Manages Solution-Problem associations
class Registry {
    public:
        bool /*has the problem been deleted?*/addSolutionToProblem(Solution*,Problem*);
        void deleteSolutionToProblem(Solution*,Problem*);
    protected:
        Registry() {}
    private:
        // Fast N-N range access
        multimap<Problem*,Solution*> psregistry;
        multimap<Solution*,Problem*> spregistry;
};

请记住不要违反SRP - Single Responsibility Principle,即:如果您必须在代码中放置newdelete,也许您可​​能想重新考虑您的设计:一个班级应该有一项任务(虽然是一项复杂的任务)。

从问题中谁不知道谁拥有问题 - 解决方案关联(N-N?1-N?)的性质以及您应该提供哪种访问,这一点尚不清楚,因此很难在此提供独特的解决方案。请注意这些详细信息,如果只有一个shared_ptr实例可以在多个专有Problem对象之间共享并需要清理,请考虑使用Solution