C ++ / CLI:声明嵌套值类型的句柄时出现编译器错误

时间:2013-04-22 14:52:18

标签: .net c++-cli

当我向嵌套值类型声明句柄时,Visual Studio(2008和2010)给出了以下编译器错误:

error C2248: 'Outer::Inner' : cannot access private struct declared in class 'Outer'

这是无法编译的代码:

ref class Outer
{
private:
    value struct Inner { };

void F()
{
    Inner i; // OK
    Inner^ h; // C2248
}
};

当我将内部的类型从值struct 更改为 ref struct 时,问题就消失了。

ref class Outer
{
private:
    ref struct Inner { };

void F()
{
    Inner i; // OK
    Inner^ h; // OK
}
};

是否存在关于我错过的嵌套值类型句柄的规则,或者这是一个VS错误?

1 个答案:

答案 0 :(得分:3)

  Inner^ h; // C2248

这是C ++ / CLI中的非常常见错误,这是您在C#和VB.NET等其他.NET语言中永远无法犯的错误。自动确定类型是声明中的值类型还是引用类型的语言。这个帽子被添加到C ++ / CLI语法中,使其类似于C ++。

创建对值类型值的引用需要将值存储在垃圾回收堆上。这称为“装箱转换”,该值嵌入​​在一个对象中。否则就会产生一种幻觉,它会产生结构类型从继承自Object的ValueType继承的错觉。在少数情况下需要使用Boxing转换,例如调用从System :: Object(Equals,GetHashCode,ToString)继承的虚方法。编译器会在没有您帮助的情况下处理,自动发出装箱转换代码。

故意装箱这个价值,就像你的陈述一样,几乎没有实际用途。我想不出任何,但这可能是由于我缺乏想象力。在访问变量时,您将调用的装箱和取消装箱代码只会增加大量开销,从而降低代码速度。价值类型被发明为加速代码,你可以尽可能地避免拳击。

解释编译器错误并不容易。有人可能会争辩说,编译器不允许访问使拳击成为可能的类型内部因为它是私有的。但很难做出这种情况,请注意调用i.ToString()会产生相同的错误。虽然它是一个私人引用类型是好的。可访问性永远不应该取决于类型的类型,这种不一致通常被称为“bug”;)您可以发布到connect.microsoft.com来制作您的案例。

最好的解决方法是理智的:只是不要使用帽子。当您想要引用语义时声明引用类型。