【问题标题】:Mixed management in C++C++中的混合管理
【发布时间】:2016-12-07 23:53:47
【问题描述】:

我在我的程序中添加了一个类并对其进行了测试。我真的很惊讶有任何真正的错误。代码如下:

#pragma once
#include "Iingredient.h"
#include <string>
#include <vector>

using namespace std;

ref class Recipe{
private:
    string partsName;
    vector<Iingredient> ing;
public:
    Recipe(){}

};

以下是错误:

错误 23 错误 C4368:无法将“partsName”定义为托管的成员 '配方':混合类型不是 支持 c:\users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 10 1 文件2_L1

错误 24 错误 C4368:无法将“ing”定义为托管的成员 '配方':混合类型不是 支持 c:\users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 11 1 文件2_L1

我用谷歌搜索了一下,发现它是关于托管和非托管代码的。 如何解决这个问题?它是否与托管和非托管代码有关?如果有怎么办?

【问题讨论】:

  • 不要这样做using namespace std;,它最终会带你走上你不想走的路。
  • 您有问题吗? SO 不是博客。

标签: c++-cli managed


【解决方案1】:

我同意其他人的观点:在大多数情况下,您不应该使用 C++/CLI,而应该使用 C#(或另一种“普通”托管语言)(假设您要编写一个 .Net 应用程序)。 C++/CLI 主要在特殊情况下很有用,例如托管代码和非托管代码之间的互操作。

如果您确定要使用 C++/CLI,则不能将本机类放入托管类。但是您可以将 指针 放在那里:

ref class Recipe{
private:
    string* partsName;
    vector<Iingredient>* ing;
};

上面的代码有效。但是您必须记住,这些是普通的本地 C++ 指针,这意味着您必须手动 delete 它们。要实现该属性,您应该了解析构函数和终结器在 C++/CLI 中的工作方式。

【讨论】:

    【解决方案2】:

    在定义ref class Recipe 时,您将其设为托管。但是std::stringstd::vector 是非托管类型。您试图在托管类中声明本机变量,但这是不允许的。

    看来,你是 C++ 的新手。只是,不要使用 C++/CLI。如果您以 .Net 或非托管 C++ 为目标,请考虑 C#。

    【讨论】:

    • +1 建议初学者不要使用 C++-cli,它比 C# 或 C++ 复杂得多(它们本身就足够复杂)
    • 所以要完成这项工作,我只需要删除 ref 以使其成为普通的 C++ 类。我在visual studio中使用并添加了类按钮,它生成了这样的类,所以我认为它必须是正确的。谢谢。
    • 在课堂前面使用“ref”这个词是什么意思? @Povylas
    【解决方案3】:

    您不能在托管类中使用非托管类型,ref 关键字,因为堆和托管堆是两种不同类型的内存。要解决此特定问题,您可以使用托管字符串类型 (System::String^)。胡萝卜告诉编译器该类型是托管类的句柄。

    解决此问题的另一种方法是使用指针,这样指针将位于托管堆上,而该对象的实际内存将位于标准非托管堆中,即Recipe 所在的位置。

    要构建您的 Recipe 类,您必须这样做

    Recipe^ recipe = gcnew Recipe();
    

    【讨论】:

    • 如果我想使用 "System::String^" -> 我应该在代码的上方使用“include 的语句还是应该使用“使用命名空间”的语句什么”?@Patrizio....
    【解决方案4】:

    在不了解 c++-cli 的情况下,我可以尝试猜测问题在于您正在定义一个引用类型并尝试在内部使用 C++ 类型(std::string 字段),而不是任何等效的托管类型( String?)。

    这可能有问题的原因是它混合了资源管理方法。引用类型旨在用于垃圾收集器之外,除非您实现析构函数或IDisposable,否则一旦证明最后一个引用丢失,就会被忽略。另一方面,为了能够管理内部字段中的内存,必须调用 std::string 析构函数。

    【讨论】:

      猜你喜欢
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      • 2015-05-20
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多