簡體   English   中英

什么是沒有數據成員的抽象類的編譯器生成的構造函數

[英]What is Compiler Generated constructor for abstract class no data members

我正在運行靜態分析工具,但由於沒有數據成員的抽象類沒有構造函數,因此出現錯誤。

給定一個沒有數據成員的抽象類:

class My_Interface
{
  public:
    virtual void interface_function(void) = 0;
};
  1. 編譯器會生成任何構造函數嗎?
  2. 如果生成了構造函數,它的內容是什么?
  3. 如果生成了構造函數,是否可以通過優化級別將其消除?

靜態分析中的規則文檔說:
如果您沒有在一個類中編寫至少一個構造函數,則默認情況下,編譯器將為您編寫一個公共構造函數。 此規則檢測您是否未聲明至少一個構造函數。

規則文檔參考了Scott Meyers,“有效的C ++:改進程序和設計的55種特定方法”,第三版。

我的理解是,編譯器不會為上述情況生成構造函數。

編輯1:
這不是許多構造函數問題的重復,因為:

  1. 這個沒有數據成員。
  2. 這不是在詢問是否需要構造函數,而是在不提供構造函數時會發生什么。
  3. 這是C ++語言。

即使在這種情況下,編譯器至少在理論上也可以合成構造函數。 即使您不能創建此類的實例,也將在創建派生類的過程中調用構造函數(該類重寫interface_function ,因此可以實例化)。

鑒於這基本上是一個純接口類,構造函數可能不會做任何事情,因此大多數編譯器可能會對其進行優化(即使您不告訴它優化代碼也可能如此)。

  1. 編譯器會生成任何構造函數嗎?

是。 一些。 首先,來自[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;
  1. 如果生成了構造函數,它的內容是什么?

全部三個都生成,所有三個都是= default;

  1. 如果生成了構造函數,是否可以通過優化級別將其消除?

這三個構造函數都不是簡單的,因為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.

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