簡體   English   中英

向右強制轉換為void *指針

[英]Right cast for a void* pointer

我正在嘗試使用一個可以指向任何value字段實現C ++類(有點像boost :: any)。 目前,我正在執行以下操作:

class MyClass {
  void* value;
  template<typename T>
  Myclass(const &T v) {
    value = (void*)(new T(v));
  }
};

現在的問題是實現一個getValue()操作,該操作創建具有正確類型的內部值的副本:

template<typename T>
T getValue() {
 return *value;
}

在這里它不能工作,因為我試圖取消引用void *指針。 我想知道應該使用哪種類型的轉換(static_cast?dynamic_cast?other ...),以便將* value正確轉換為T對象,並且如果value最初不是這種類型,則會引發異常?

謝謝

您不能取消引用void* ,這根本沒有意義。 為什么不使類本身具有泛型? 然后您可以擁有:

template<typename T>
class MyClass {
  T* value;

  MyClass(const T& v) {
    value = new T(v);
  }

  T getValue() {
    return *value;
  }
};

確保創建一個析構函數,該析構函數可以分配value並遵循“三法則” 您也可以創建一個getValue版本,該版本返回const T& (指向T const引用)以避免不必要的復制。

我應該使用哪種轉換(static_cast?dynamic_cast?other ...),以便將* value正確轉換為T對象

如果必須執行此轉換,則應使用static_cast ,通常將其用於(除其他事項外)撤消任何標准轉換。 從任何對象指針類型到void*都有標准轉換,您的getter會將其反轉,因此請使用為此設計的強制轉換:

return *static_cast<T*>(value);

您還應該從構造函數中刪除C樣式static_cast ,或者也將其替換為static_cast

reinterpret_cast也可以,但是“過度殺傷”。 通常,在執行所需轉換的同時,應使用盡可能嚴格的轉換。

如果value最初不是此類型,則拋出異常

您真不走運-一旦將指針轉換為void* ,C ++通常就無法確定對象的原始類型是什么。 您的代碼依賴於調用方以正確的類型調用getValue 例如,考慮一下如果原始類型是char ,會發生什么情況-在C ++中只有一個字節,那么就沒有為任何類型信息留出空間,這將允許編譯器檢查getValue中的getValue

dynamic_cast在某些有限的情況下會檢查類型,但是由於您的模板是完全通用的,因此這些有限的情況可能不適用。

如果您不喜歡這樣做,則除了對象指針外,還可以更改類以存儲指向type_info對象的指針(使用typeid運算符)。 參見標准標題<typeinfo> 然后,您可以比較type_info對象類型T的構造,與type_info的對象類型TgetValue ,並拋出,如果他們不匹配。

就像您說的那樣,您的類打算有點像boost::any ,而getValue就像any_cast 您可以查閱該類的源代碼和文檔,以了解完成所需的技巧。 如果有一種簡單的方法,那么boost::any將是一個簡單的類!

你不能 C ++不會(至少不是直接)提供這種機制,不是針對void* void*沒有任何信息表明計算機將需要確定它是什么,並且嘗試“檢查”它是否是有效的(隨便播報)是不可能的,因為沒有針對它的特定標志。

雖然有選擇。 首先是使用某種類似於Java的Object的通用基類,並從中派生所有其他類。 現在, dynamic_cast將按照您想要的方式工作(如果對象不是將其強制轉換為的類的有效對象,則返回NULL )。

另一個是簡單地跟蹤您自己屬於哪種類型的對象。 這意味着用另一個值擴展void* ,它告訴您需要將其強制轉換為什么。

但是,實際上,這些東西都不是我的好主意。 我認為您的設計中幾乎有其他方面應該更改而不是使用這些方面。 使用模板,如@EdS。 建議,例如,這是一個非常好的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM