【问题标题】:C++ / C# ABC design pattern with static member带有静态成员的 C++/C# ABC 设计模式
【发布时间】:2013-08-05 16:05:46
【问题描述】:

我有一个 ABC 类,我想将其设为通用:

struct BinaryVariable {
  static const int N = 2;
  static std::string outcome_names[N] = { "heads", "tails" };
};

struct EvidenceBinaryVariable : public BinaryVariable {
  double likelihoods[ BinaryVariable::N ];
};

struct LatentBinaryVariable : public BinaryVariable { };

重要的是这三个节点的每个实例共享相同的::N,并为outcome_names 变量使用相同的内存。

假设我想让这三种节点类型也允许具有 6 种可能结果的变量(即,除了硬币之外,我还想支持骰子)。在 C++ 中,我可以使用模板来做到这一点:

#include<cstddef>
#include<string>

template<std::size_t N>
struct DiscreteVariable {
  static std::string outcome_names[N];
};

template<std::size_t N>
struct EvidenceVariable : public DiscreteVariable<N> {
  double likelihoods[ DiscreteVariable::N ];
};

template<std::size_t N>
struct LatentVariable : public DiscreteVariable<N> { };

int main()
{
    LatentVariable<2> schrodingers_coin;
    LatentVariable<6> schrodingers_die;
}

如果不使用模板,我无法想出一种方法让这三种类型拥有一个静态 outcome_names 成员(其中 shrodingers_coin.outcome_namesschrodingers_dice.outcome_names 不引用同一块静态内存)方式。

C# 仅支持基于类型的模板(即您可以提供 &lt;int&gt; 但不能提供 &lt;6&gt;

第一个问题:C++ 中有没有一个好的设计模式? (例如,我应该将这些三元组用作大师班的内部课程吗?)

第二个问题:这种好的设计模式是否适用于 C#(或者 C++ 的模板魔法正好适合这里)?

只是为了后代,我想要这些静态的原因是因为我有大量这些对象,并且正在编写效率至高无上的东西(想想大数据)。

非常感谢您的帮助。

【问题讨论】:

  • OP:我编辑了您的 C++ 代码,至少使其成为有效代码。
  • 几个问题。首先,LatentVariable&lt;2&gt; foo;LatentVaraible&lt;2&gt; bar; 是否应该指向同一个DiscreteVariable 字符串数组?如果不是,那么您不希望 outcome_names[] 是静态的。其次,这是组合比继承更有意义的一个例子; DiscreteVariable,或者更确切地说outcome_names[] 应该是LatentVariable 的成员(可能是非静态的,取决于第一个问题的答案)。
  • @Aggieboy 我希望它们引用相同的内存(对于给定大小的所有对象,变量的名称应该相同,并且我想避免每个项目只有一个副本) .关于继承,对我来说这确实是一种“是”类型的依赖,但也许你是说这可以通过组合简化维护?怎么样?
  • @NeilKirk 枚举是个好主意,但我希望能够遍历结果名称:cout &lt;&lt; outcome_names[i] &lt;&lt; " had likelihood " &lt;&lt; likelihoods[i];
  • 如果您的枚举是连续的(0、1、2..)并且您调用最后一个枚举 name_max 或其他内容,您可以迭代 0

标签: c# c++ templates static-members


【解决方案1】:

您的 DiscreteVariable 类只是一个枚举,因此请使用枚举。这就是我在 C# 中实现它的方式:

enum SchrodingersCoin
{
    Heads,
    Tails,
}

class Likelihood<T>
{
    public static double[] likelihoods;

    static Likelihood()
    {
        // Init likelihoods here using Enum.GetValues()
    }
}

C++ 实现:

enum SchrodingersCoin
{
    Head,
    Tails,
    Count,
};

template <typename T>
struct Likelihood
{
    static double likelihoods[T::Count];
};

在 C# 中,您可以轻松地将枚举转换为字符串,但在 C++ 中,您通常必须编写一个函数来为您进行转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-06
    • 1970-01-01
    相关资源
    最近更新 更多