[英]What is Compiler Generated constructor for abstract class no data members
我正在運行靜態分析工具,但由於沒有數據成員的抽象類沒有構造函數,因此出現錯誤。
給定一個沒有數據成員的抽象類:
class My_Interface
{
public:
virtual void interface_function(void) = 0;
};
靜態分析中的規則文檔說:
如果您沒有在一個類中編寫至少一個構造函數,則默認情況下,編譯器將為您編寫一個公共構造函數。 此規則檢測您是否未聲明至少一個構造函數。
規則文檔參考了Scott Meyers,“有效的C ++:改進程序和設計的55種特定方法”,第三版。
我的理解是,編譯器不會為上述情況生成構造函數。
編輯1:
這不是許多構造函數問題的重復,因為:
即使在這種情況下,編譯器至少在理論上也可以合成構造函數。 即使您不能創建此類的實例,也將在創建派生類的過程中調用構造函數(該類重寫interface_function
,因此可以實例化)。
鑒於這基本上是一個純接口類,構造函數可能不會做任何事情,因此大多數編譯器可能會對其進行優化(即使您不告訴它優化代碼也可能如此)。
- 編譯器會生成任何構造函數嗎?
是。 一些。 首先,來自[class.ctor]:
類X的默認構造函數是類X的構造函數,它沒有參數,或者不是函數參數包的每個參數都有一個默認參數。 如果類X沒有用戶聲明的構造函數,則將不帶參數的非顯式構造函數隱式聲明為默認值(8.4)。 隱式聲明的默認構造函數是其類的內聯公共成員。 如果滿足以下條件,則將X類的默認默認構造函數定義為已刪除:
接下來是幾個要點,都不適用。 因此,我們具有:
My_Interface() = default;
然后,從[class.copy]:
如果類定義未顯式聲明一個副本構造函數,則將隱式聲明一個非顯式的構造函數。 如果類定義聲明了move構造函數或move賦值運算符,則隱式聲明的copy構造函數將定義為delete; 否則,將其定義為默認值(8.4)。
因此,我們有:
My_Interface(const My_Interface&) = default;
也:
如果類X的定義未明確聲明移動構造函數,則僅當且僅當非顯式類的隱式聲明為默認值
(9.1)— X沒有用戶聲明的副本構造函數,
(9.2)— X沒有用戶聲明的副本分配運算符,
(9.3)— X沒有用戶聲明的移動分配運算符,並且
(9.4)— X沒有用戶聲明的析構函數。
因此,我們還有:
My_Interface(My_Interface&& ) = default;
- 如果生成了構造函數,它的內容是什么?
全部三個都生成,所有三個都是= default;
- 如果生成了構造函數,是否可以通過優化級別將其消除?
這三個構造函數都不是簡單的,因為My_Interface
具有虛函數。 這樣,至少需要對vtable進行初始化/復制。 因此,即使沒有任何要初始化/復制/移動的成員,也將發生某些事情 。
Q1。 編譯器會生成任何構造函數嗎?
答:可以。 從C ++ 11標准:
12.1構造函數
5.一種A類默認的構造
X
是類的構造函數X
,可以不帶參數被調用。 如果類X
沒有用戶聲明的構造函數,則將不帶參數的構造函數隱式聲明為默認值(8.4)。 隱式聲明的默認構造函數是其類的inline public
成員。
我在標准中看不到能回答其他兩個問題的任何內容。 但是,在您的情況下,由於存在virtual
成員函數,因此默認構造函數必須至少設置對象的虛擬表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.