【问题标题】:C++ assigning managed pointers to an object with and without the address operator "%"C ++将托管指针分配给带有和不带有地址运算符“%”的对象
【发布时间】:2015-08-19 21:28:08
【问题描述】:

我对 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 确实返回了一个对象,那么它不应该给我一个无法将DateTime 转换为DateTime^ 的错误吗?似乎为了让第二个工作,DateTime::Now 需要返回由DateTime::Now 创建的DateTime 对象的引用,在这种情况下,第一个dt = %DateTime::Now 不应该给出类似的错误 cannot将DateTime^^ 转换为DateTime^ 还是智能指针与普通指针的工作方式不同?

【问题讨论】:

  • 语言错误。不是 C++。
  • 类型后面的^和“指针”前面的%是什么???你确定你在学习 C++? :)
  • 这是带有托管扩展的 C++。这是您使用 C++ 编写 .NET 代码的方式。
  • @Darryl 所以,它不是 C++。或许你能帮忙找到合适的标签?

标签: datetime pointers c++-cli memory-address managed


【解决方案1】:

将 dt 指针设置为 DateTime::Now 返回的对象的引用

这就是你出错的地方,DateTime::Now not 返回一个对象。它返回一个value,DateTime 是一个值类型。引用类型和值类型之间的区别在 C++ 中完全没有,但在 .NET 中却很重要。您必须了解它才能编写高效的代码,这非常不是高效。

日期时间^ 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);

【讨论】:

  • Nullable 基本上不是装箱值类型吗?我希望您建议的代码版本与原始代码基本相同。
  • 不,Nullable 是一个结构。一种值类型。在 sn-p 中的任何地方都不会发生装箱。它被添加到 .NET 以避免装箱。编译器知道它是如何工作的,他们将 HasValue 字段设置为 true 而无需显式编写该赋值。
猜你喜欢
  • 2018-10-12
  • 2013-09-09
  • 2012-02-23
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多