Dot-Net
this == null // 怎麼可能?
最近我遇到了我的應用程序的一些奇怪行為。它主要使用 C# 開發,但也使用 CLI/C++ 來實現更好的性能。在 TimeSpan 比較中,我以一種非常簡單的方法得到了 System.NullReferenceException:
TimeSpan _timestamp; void UpdateFrame(TimeSpan timestamp) { if(TimeSpan::Equals(_timestamp, timestamp) == false)很明顯,這個表達式中使用的唯一引用是隱含的 this (this._timestamp)。我添加了一個斷言語句,結果證明這實際上是空的。經過短暫的調查,我設法準備了介紹這種現象的短節目。它是 C++/CLI。
using namespace System; using namespace System::Reflection; public class Unmanaged { public: int value; }; public ref class Managed { public: int value; Unmanaged* GetUnmanaged() { SampleMethod(); return new Unmanaged(); } void SampleMethod() { System::Diagnostics::Debug::Assert(this != nullptr); this->value = 0; } }; public ref class ManagedAccessor { public: property Managed^ m; }; int main(array<System::String ^> ^args) { ManagedAccessor^ ma = gcnew ManagedAccessor(); // Confirm that ma->m == null System::Diagnostics::Debug::Assert(ma->m == nullptr); // Invoke method on the null reference delete ma->m->GetUnmanaged(); return 0; }有誰知道這怎麼可能?它是編譯器中的錯誤嗎?
在 C++ 中(可能是在 C++/CLI 中),沒有什麼可以阻止您嘗試在 NULL 指針上呼叫方法。在大多數實現中,虛擬方法呼叫將在呼叫點崩潰,因為執行時將無法讀取虛擬方法表。但是,非虛擬方法呼叫只是帶有一些參數的函式呼叫,其中一個參數是
this指針。如果它為空,那麼這就是傳遞給函式的內容。
NULL我相信在(或)指針上呼叫任何成員函式的結果nullptr是正式的“未定義行為”。