簡體   English   中英

靜態函數在 C++ 中可以是虛擬的嗎?

[英]Can static functions be virtual in C++?

我發現了一些關於我上述問題的陳述,但有不同的說法:

  1. 靜態成員函數不能訪問類的非靜態數據成員/函數。 vPTR 是非靜態數據成員,因此靜態成員函數不能訪問 vPTR。

  2. 不,因為它在 C++ 中沒有任何意義。

    當您擁有指向類實例的指針/引用時,將調用虛擬函數。 靜態函數不綁定到特定實例,它們綁定到一個類。 C++ 沒有指向類的指針,因此不存在您可以虛擬調用靜態函數的情況。

哪個是正確的,原因是什么?

不,靜態函數在 C++ 中不能是虛擬的。

如果函數不依賴於類的任何成員,但在某種意義上依賴於類型,它偶爾會很有用:

struct Animal
{
    static virtual std::string whatNoiseDoIMake() = 0;
};

struct Dog : Animal
{
    static std::string whatNoiseDoIMake()
    {
        return "woof"s;
    }
};

它不是語言的一部分的原因是它沒有被 C++ 標准委員會提議和接受。 我的示例可以使用類型特征來解決,這削弱了允許此類構造的情況。

至於const ,那確實是關於修改非mutable類成員的可能性。 很難編造一個有意義的const static成員函數示例。 也許它可以應用於static成員,但是這樣的成員可以通過::訪問(有趣的是)訪問說明符被丟棄。

哪個是正確的,確切原因是什么?

  1. 靜態成員函數不能訪問類的非靜態數據成員/函數。 vPTR 是非靜態數據成員,因此靜態成員函數不能訪問 vPTR。

  2. 不,因為它在 C++ 中沒有任何意義。

    當您擁有指向類實例的指針/引用時,將調用虛擬函數。 靜態函數不綁定到特定實例,它們綁定到一個類。 C++ 沒有指向類的指針,因此不存在您可以虛擬調用靜態函數的情況。

第一條語句是正確的,就靜態成員函數無法訪問*this指針而言,它們具有類作用域。 靜態成員由類的所有實例共享

在第二個陳述中,第一部分是基於意見的,正如@Bathsheba 指出的那樣,可以爭辯說它可能有用。 第二部分是正確的。

不管使用這種構造的可能意義或優點如何,標准很清楚為什么不允許虛擬靜態成員函數:

11.7.2 虛函數[class.virtual#11]

[ 注意:虛擬說明符意味着成員資格,因此虛擬函數不能是非成員 ( [dcl.fct.spec] ) 函數。 虛函數也不能是靜態成員,因為虛函數調用依賴於特定對象來確定要調用哪個函數。 在一個類中聲明的虛函數可以在另一個類中聲明為友元( [class.friend] )。 — 尾注 ]

不,他們不能。

虛擬成員旨在處理類的實例

靜態成員不處理實例,它們只與類有關

您將如何根據實例(如在動態多態中)選擇要調用的“虛擬靜態”函數,因為與任何實例都沒有連接?

這只是兩種不同的機制,它們具有相互排斥的依賴關系。

靜態函數在 C++ 中可以是虛擬的嗎?

不。

靜態成員函數不能訪問類的非靜態數據成員/函數。

這不太正確:靜態方法絕對可以訪問非靜態(實例)成員......如果你給他們一個實例。 他們有access ,他們只是沒有默認的this對象來操作。

vPTR 是非靜態數據成員,因此靜態成員函數不能訪問 vPTR

我們不需要糾結於諸如 vtables 之類的實現細節。 可以說虛擬分派取決於對象的動態類型就足夠了,如果您沒有對象,則沒有可能從虛擬分派中受益的類型歧義。

C++ 沒有指向類的指針,因此不存在您可以虛擬調用靜態函數的情況

請注意,在具有此功能的語言中,您仍然不需要用於靜態虛擬的特殊系統 - 通常只是類對象。 因此,在這種情況下,常規類的靜態方法仍然是類object 的實例方法。

第一個語句假定一個“vptr”。 這指的是 C++ 編譯器中的一種常見實現技術,其中每個具有虛函數的對象都包含一個指向某個“vtable”的隱藏指針,該指針又包含指向虛函數的指針。

然而,這是這些編譯器的實現細節。 他們選擇該實現是因為它是 C++ 標准允許的可能實現。

允許它的原因之一是因為 C++ 標准說你總是需要一個對象來調用虛函數,所以總是有一個對象來存儲“vptr”。

因此,第一個答案混淆了因果關系。 實現可以使用“vptr”,因為虛函數需要一個對象,因此不能是static ,反之亦然。

靜態函數在 c++ 中不能是虛擬的,因為這個概念會導致編譯錯誤並且基本上在運行時解決

暫無
暫無

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

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