【问题标题】:How do I create a CLI value class containing a List (or similar) which is passed by value?如何创建包含按值传递的列表(或类似)的 CLI 值类?
【发布时间】:2010-01-18 10:35:30
【问题描述】:

我们有一个 C++ 库,它使用一个包含结构体的 STL 向量的结构体,如下所示:

struct Params
{
    // values...
}

struct Settings
{
    std::vector<Params> m_params;

    // values...
}

我正在为库编写 CLI 包装器,并且我想要上述结构类型的等价物。我一直在考虑使用 List 作为向量的等价物,如下所示:

public value struct Params
{
    // values...
}

public value struct Settings
{
    List<Params>^ Params;

    // values...
}

但由于 List 是引用类型,因此列表是通过引用而不是值传递的。有没有办法创建一个 CLI 类,其中包含一个按值传递的列表(或类似列表)以及其他成员?

【问题讨论】:

  • “但是因为List是一个值类型”List是一个引用类型,而不是一个值类型。
  • @Mehrdad:很好,谢谢。固定。

标签: c++-cli pass-by-reference pass-by-value


【解决方案1】:

我同意 mcdave 的回答,归结为不支持您的要求。

我推测您的主要观点不是获得实际传递值,而是更多地获得传递值行为。想想System.String。那不是真正的值类型,但您可以安全地传递引用,因为字符串不能被修改,您只能创建新的。

要获得相同的列表,您可以将Params 设为IList&lt;Param&gt; 类型的属性。分配时,将内容复制到新的List&lt;Param&gt; 中,并存储调用AsReadOnly() 时获得的IList 指针。从现在开始,IList 指向一个无法修改的对象。如果结构是按值传递的,则指针将被复制,但这没关系,因为它指向不可变的东西。如果您的对象被大量传递,它也会更快,因为不需要每次都进行深度复制。

【讨论】:

  • 你说的很对——字符串等效的行为就足够了。
【解决方案2】:

我认为您不能通过值传递设置类,因为“值类型不能包含用户定义的特殊成员函数”(from C3417),例如复制构造函数。

您可以使用以下方法实现类似的效果:

public value struct Settings : public ICloneable
{
    List<Params>^ m_params;

    virtual Object^ Clone()
    {
        Settings^ rv = gcnew Settings();
        rv->m_params = gcnew List<Params>();
        rv->m_params->AddRange(m_params->ToArray());
        return rv;
    }
}

在您的 C# 代码中,您将拥有:

Settings s1, s2;
// ... some code modifying s1
s2 = (Settings)s1.Clone();

这几乎与您通过值传递获得的 Settings settings1 = settings2; 样式语法一样干净。

【讨论】:

    【解决方案3】:

    List&lt;Params&gt;^% Params; 或者 List&lt;Params%&gt;^% Params; 怎么样?

    【讨论】:

      猜你喜欢
      • 2011-12-12
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 2019-05-18
      • 2021-11-21
      相关资源
      最近更新 更多