यह संभव नहीं है, लेकिन यह सिर्फ एक चूक है। यह ऐसा कुछ नहीं है जो "समझदारी नहीं करता है" जैसा कि बहुत सारे लोग दावा करते हैं। स्पष्ट होने के लिए, मैं कुछ इस तरह की बात कर रहा हूं:
struct Base {
static virtual void sayMyName() {
cout << "Base\n";
}
};
struct Derived : public Base {
static void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
Derived::sayMyName(); // Also would work.
}
यह 100% कुछ है जिसे लागू किया जा सकता है (यह सिर्फ नहीं है), और मैं कुछ ऐसा तर्क दूंगा जो उपयोगी है।
इस बात पर विचार करें कि सामान्य वर्चुअल फ़ंक्शन कैसे काम करते हैं। एस निकालें static
और कुछ अन्य सामानों में जोड़ें और हमारे पास हैं:
struct Base {
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
}
यह ठीक काम करता है और मूल रूप से क्या होता है संकलक दो टेबल बनाता है, जिसे वीटीएबल्स कहा जाता है, और इस तरह के आभासी कार्यों के लिए सूचकांक प्रदान करता है
enum Base_Virtual_Functions {
sayMyName = 0;
foo = 1;
};
using VTable = void*[];
const VTable Base_VTable = {
&Base::sayMyName,
&Base::foo
};
const VTable Derived_VTable = {
&Derived::sayMyName,
&Base::foo
};
वर्चुअल फ़ंक्शंस के साथ प्रत्येक वर्ग को एक अन्य फ़ील्ड के साथ संवर्धित किया जाता है जो उसके VTable को इंगित करता है, इसलिए कंपाइलर मूल रूप से उन्हें इस तरह बदलता है:
struct Base {
VTable* vtable;
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
VTable* vtable;
void sayMyName() override {
cout << "Derived\n";
}
};
जब आप कॉल करते हैं तब वास्तव में क्या होता है b->sayMyName()
? मूल रूप से यह:
b->vtable[Base_Virtual_Functions::sayMyName](b);
(पहला पैरामीटर बन जाता है this
।)
ठीक है, तो यह स्थिर आभासी कार्यों के साथ कैसे काम करेगा? वैसे स्थैतिक और गैर-स्थैतिक सदस्य कार्यों में क्या अंतर है? अंतर केवल इतना है कि बाद वाले को एक this
सूचक मिलता है ।
हम स्थैतिक आभासी कार्यों के साथ बिल्कुल वैसा ही कर सकते हैं - बस this
पॉइंटर को हटा दें ।
b->vtable[Base_Virtual_Functions::sayMyName]();
यह तब दोनों सिंटैक्स का समर्थन कर सकता है:
b->sayMyName(); // Prints "Base" or "Derived"...
Base::sayMyName(); // Always prints "Base".
इसलिए सभी नैय्यर्स को नजरअंदाज करें। यह करता है मेकअप भावना। यह तब क्यों समर्थित नहीं है? मुझे लगता है कि यह इसलिए है क्योंकि इसका बहुत कम लाभ है और थोड़ा भ्रमित भी हो सकता है।
एक सामान्य आभासी फ़ंक्शन पर केवल तकनीकी लाभ यह है कि आपको फ़ंक्शन को पास this
करने की आवश्यकता नहीं है, लेकिन मुझे नहीं लगता है कि प्रदर्शन के लिए कोई औसत दर्जे का अंतर होगा।
इसका मतलब है कि आपके पास मामलों के लिए एक अलग स्थिर और गैर-स्थिर फ़ंक्शन नहीं है जब आपके पास एक उदाहरण है, और जब आपके पास कोई उदाहरण नहीं है, लेकिन यह भी भ्रमित हो सकता है कि यह केवल "वर्चुअल" है जब आप उपयोग करते हैं उदाहरण कॉल।
const
एक विधि हस्ताक्षर में निहितthis
सूचक को स्थिर के रूप में चिह्नित करता है और स्थैतिक तरीकों पर लागू नहीं किया जा सकता है क्योंकि उनके पास निहित पैरामीटर की कमी है।