C++将托管指针分配给具有和不使用地址运算符的对象"%"



我对c++比较陌生,正在学习如何使用指针,但是我遇到了一些让我对它们赋值感到困惑的事情。我有类似下面的代码:

DateTime^ dt;
...
while(true)
{
    if(!dt)
    {
        //both of these work - compile and the loop will break after a minute
        //dt = DateTime::Now;
        dt = %DateTime::Now;
    }
    else if ((DateTime::Now - *dt).TotalMilliseconds > 60000)
    {
         break;
    }
}

为什么这两种方法都有效?根据我的理解,dt = %DateTime::Nowdt指针设置为DateTime::Now返回的对象的引用,这对我来说是无效的。但是在dt = DateTime::Now中发生了什么,因为如果DateTime::Now确实返回一个对象,那么它不应该给我一个不能转换DateTimeDateTime^的错误吗?似乎为了第二个工作,DateTime::Now需要返回DateTime::Now创建的DateTime对象的引用,在这种情况下,第一个dt = %DateTime::Now不应该给出类似的错误,不能将DateTime^^转换为DateTime^,或者智能指针的工作方式与普通指针不同?

将dt指针指向DateTime::Now

返回的对象的引用。

这就是你出错的地方,DateTime::现在返回对象。它返回一个, DateTime是一个值类型。引用类型和值类型之间的区别在c++中是完全不存在的,但在。net中是一个非常重要的问题。你必须理解它才能写出高效的代码,这非常不是高效。

DateTime ^ dt;

这就是火车脱轨的地方,因为DateTime是一个值类型,你应该声明这个变量而不带 ^帽。遗憾的是,c++/CLI编译器允许这种语法并实际实现了它。该变量存储值的盒装副本。有意地对值进行装箱是您总是希望避免的事情,装箱转换并不便宜。而。net拥有值类型的全部意义在于使程序更快。

但是,是的,正如您发现的那样,c++/CLI编译器知道如何将值框起来,而不必明确说明它。虽然应该避免,但有时值被框起来并不罕见。例如,不能调用虚拟ToString()方法。所以你不必使用%。装箱创造了一种假象,即所有的值类型都派生自System::Object。

如果(dt)

我必须假设这就是你真正想要的,检测变量"未初始化"。在。net中有一个更有效的模式,你可以使用Nullable<>类型。这样的:

Nullable<DateTime> dt;
while (true) {
    if (!dt.HasValue) {
        dt = DateTime::Now;
    }
    else if ((DateTime::Now - dt.Value).TotalMilliseconds > 60000) {
        break;
    }
}

可以通过许多方式进行改进,您可以使用:

来避免半途而废的版本
System::Threading::Thread::Sleep(60000);

相关内容

  • 没有找到相关文章

最新更新