[英]Can static functions be virtual in C++?
我發現了一些關於我上述問題的陳述,但有不同的說法:
靜態成員函數不能訪問類的非靜態數據成員/函數。 vPTR 是非靜態數據成員,因此靜態成員函數不能訪問 vPTR。
不,因為它在 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
成員,但是這樣的成員可以通過::
訪問(有趣的是)訪問說明符被丟棄。
哪個是正確的,確切原因是什么?
靜態成員函數不能訪問類的非靜態數據成員/函數。 vPTR 是非靜態數據成員,因此靜態成員函數不能訪問 vPTR。
不,因為它在 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.