C++ 的混合管理
我已经在我的程序中添加了一个类并对其进行了测试。我真的很惊讶竟然有任何真正的错误。这是代码:
#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 file2_L1
错误 24 错误 C4368:无法将“ing”定义为托管成员 '食谱':混合类型不是 支持的 c:\users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 11 1 file2_L1
我用谷歌搜索了一下,发现它是关于托管和非托管代码的。 如何解决这个问题?它是否与托管和非托管代码相关?如果是这样怎么办?
I have added a class to my program and tested it. I was really surprised that there was any real errors. Here is the code:
#pragma once
#include "Iingredient.h"
#include <string>
#include <vector>
using namespace std;
ref class Recipe{
private:
string partsName;
vector<Iingredient> ing;
public:
Recipe(){}
};
And here are the errors:
Error 23 error C4368: cannot define 'partsName' as a member of managed
'Recipe': mixed types are not
supported c:\users\user\documents\visual studio
2010\projects\smestras2_l1\Recipe.h 10 1 file2_L1Error 24 error C4368: cannot define 'ing' as a member of managed
'Recipe': mixed types are not
supported c:\users\user\documents\visual studio
2010\projects\smestras2_l1\Recipe.h 11 1 file2_L1
I googled a bit and found out that its about managed and unmanaged code.
How to fix this? Is it related with manged and unmanaged code or not? if so how?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我同意其他人的观点:在大多数情况下,您不应该使用 C++/CLI,您应该使用 C#(或其他“正常”托管语言)(假设您想编写 .Net 应用程序)。 C++/CLI 主要在特殊情况下有用,例如托管代码和非托管代码之间的互操作。
如果您确定要使用 C++/CLI,则不能将本机类放入托管类中。但是您可以将指针放在那里:
上面的代码可以工作。但您必须记住,这些是普通的本机 C++ 指针,这意味着您必须手动
删除
它们。要实现该属性,您应该了解析构函数和终结器在 C++/CLI 中的工作原理。I agree with others: you shouldn't use C++/CLI in most circumstances, you should use C# (or another "normal" managed language) for that (assuming you want to write a .Net application). C++/CLI is useful mostly in special circumstances, like interoperating between managed and unmanaged code.
If you're sure you want use C++/CLI, you can't put native classes into managed ones. But you can put pointers to native classes there:
The code above works. But you have to keep in mind that those are normal native C++ pointers and that means you have to manually
delete
them. To do that property, you should read about how destructors and finalizers work in C++/CLI.在定义
ref class Recipe
时,您将其设为托管。但std::string
和std::vector
是非托管类型。您试图在托管类中声明本机变量,但这是不允许的。看来你是C++新手。只是,不要使用 C++/CLI。如果您的目标是 .Net 或非托管 C++,请考虑 C#。
When defining
ref class Recipe
, you made it managed. Butstd::string
andstd::vector
are umanaged types. You are trying to declare native variables in managed class, but it is not allowed.Seems, you are novice in C++. Just, don't use C++/CLI. Consider C#, if you target .Net or unmanaged C++.
不能在托管类中使用非托管类型,
ref
关键字,因为堆和托管堆是两种不同类型的内存。要解决这个特定问题,您可以使用托管字符串类型 (System::String^
)。胡萝卜告诉编译器该类型是托管类的句柄。解决此问题的另一种方法是使用指针,这样指针将位于托管堆上,而该对象的实际内存将位于标准非托管堆中,这就是
Recipe
所在的位置位于。要构建您的
Recipe
类,您必须这样做You cannot use unmanaged types in a managed class,
ref
keyword, because the heap and the managed heap are two different types of memory. To solve this specific problem you can use a managed string type (System::String^
). The carrot tells the compiler that the type is a handle to a managed class.Another way of going about this problem is to use pointers, that way the pointer will be on the managed heap, and the actual memory for that object will be in the standard unmanaged heap, which is where
Recipe
is located.To construct your
Recipe
class you would have to do由于不了解 c++-cli,我可以尝试猜测问题是您正在定义引用类型并尝试在内部(
std::string
字段)使用 C++ 类型,而不是任何等效的托管类型是 (String
?)。这可能会出现问题的原因是它混合了资源管理方法。引用类型旨在在垃圾收集器之外使用,除非您实现析构函数,否则一旦证明最后一个引用丢失,
IDisposable
将被忽略。另一方面,为了能够管理内部字段中的内存,必须调用 std::string 析构函数。With no idea of c++-cli, I can try and guess that the problem is that you are defining a reference type and trying to use C++ types inside (a
std::string
field) rather than whatever the equivalent managed type is (String
?).The reason why this can be problematic is that it mixes resource management approaches. Reference types are intended to be used out of a garbage collector, and unless you implement a destructor or
IDisposable
will just be ignored once proven that the last reference is lost. On the other hand, to be able to manage the memory in the internal field thestd::string
destructor must be called.