簡體   English   中英

成員指針的大小和reinterpret_cast是否固定?

[英]are member pointers fixed in size and reinterpret_cast?

我正在嘗試創建一個包含指向任意類實例和函數的指針的模板類,如下所示:

template<class C>
class A {
   typedef void (C::*FunctPtr)(); //e.g. void C::some_funct();

   FunctPtr functPtr_;
   C* instPtr_;
public:
   A(FunctPtr functPtr, C* instPtr)
      : functPtr_(functPtr)
      , instPtr_(instPtr) {}
};

但是,我希望能夠使用placement new創建此類的實例而無需動態分配內存。 C ++標准是否保證所有C類的模板類的大小都是固定的?

Don Clugston的有關指針的文章中 ,我注意到了各種編譯器上成員函數指針的各種大小的圖表,並且一些編譯器的大小並不總是相同的。 我以為我被抽了水,但這符合標准嗎? 從C ++標准開始。 5.2.10關於重新解釋演員表:

—將類型為“指向成員函數的指針”的prvalue轉換為指向成員函數類型的不同指針,然后再返回其原始類型,將產生指向成員值的原始指針。

C ++標准中的該語句是否表示成員函數指針的大小相同?

如果不是這樣,我想我仍然可以按如下方式重寫代碼,以顯式地利用該reinterpret_cast保證:

class GenericClass;

template<class C>
class A {

   typedef void (GenericClass::*GenFunctPtr)();
   typedef void (C::*SpecificFunctPtr)();

   GenFunctPtr functPtr_; //store any kind of function ptr in this fixed format
   GenericClass* instPtr_;

public:
   A(SpecificFunctPtr functPtr, C* instPtr)
      : functPtr_(reinterpret_cast<GenFunctPtr>(functPtr))
      , instPtr_(reinterpret_cast<GenericClass*>(instPtr)) {}

   void DoSomething()
   {
      //now convert pointers back to the original type to use...
      reinterpret_cast<SpecificFunctPtr>(functPtr_);
      reinterpret_cast<C*>(instPtr_);
   }
};

現在似乎要求它的大小都相同,但要符合標准,對嗎? 我更喜歡第一種選擇,但是如果我必須選擇第二種也可以。 思考?

我不知道是否在標准中指定了指向成員的指針的實現細節(找不到它),但是由於我們知道C*對於所有C都具有相同的大小,因此我們只需確定大小即可各種類型CFunctPtr ,只需添加一個static_assert

template <class C>
class A {
   typedef void (C::*FunctPtr)(); //e.g. void C::some_funct();
   static_assert(sizeof(FunctPtr) == 16, 
       "unexpected FunctPtr size"); // from coliru, clang and gcc

   FunctPtr functPtr_;
   C* instPtr_;
   ...
};

至少我用幾種類型的類({基本,派生,多個派生} x {虛擬,非虛擬})進行了嘗試,並且始終提供相同的大小。

這可能是特定於平台和/或編譯器的,因為指向成員函數的指針是非常奇怪的動物,它表明:

僅使用單一繼承的類的指向成員函數的指針的大小僅是指針的大小。
使用多重繼承的類的指向成員函數的指針的大小是指針的大小加上size_t的大小。

這不是我在clang或gcc中看到的。

Microsoft編譯器根據類的復雜程度使用不同大小的成員指針。 從技術上講,這是不合規的(因為即使在類定義不可見的情況下,您也可以定義指向成員的指針),但是在實踐中它可以很好地工作,默認情況下它們會這樣做。 實用程序和編譯器開關可用於控制此行為。 參見例如https://msdn.microsoft.com/en-us/library/83cch5a6.aspx

即使任何給定類的指針始終具有相同的大小,只是不同的類可能具有指向成員的大小不同的指針。

暫無
暫無

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

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