वास्तव में यह एक साक्षात्कार प्रश्न है, मैं जवाब नहीं समझ सकता। किसी को इसके बारे में पता है? आप किसी भी अंतर के बारे में बात कर सकते हैं, उदाहरण के लिए, स्टैक में धक्का देने वाला डेटा।वर्चुअल फ़ंक्शन और गैर आभासी फ़ंक्शन को कॉल करने के बीच अंतर?
उत्तर
हालांकि virtualism/गतिशील प्रेषण सख्ती से कार्यान्वयन परिभाषित किया गया है, सबसे अधिक (पढ़ा सभी ज्ञात) compilers vptr
और vtable
का उपयोग करके इसे लागू।
कहा करने के बाद कि, एक गैर आभासी समारोह और आभासी समारोह बुला बीच का अंतर है:
गैर आभासी कार्यों Compile-time
पर statically
हल कर रहे हैं, जबकि आभासी कार्यों Run-time
पर dynamically
हल कर रहे हैं।
रन-टाइम पर कॉल करने के लिए कौन सा फ़ंक्शन कॉल करने में सक्षम होने की यह लचीलापन प्राप्त करने के लिए, वर्चुअल फ़ंक्शंस के मामले में थोड़ा ओवरहेड है।
एक अतिरिक्त fetch
कॉल जिसे करने की आवश्यकता है और यह गतिशील प्रेषण का उपयोग करने के लिए आपके द्वारा भुगतान किए जाने वाले ओवरहेड/मूल्य है।
गैर आभासी समारोह के मामले में कॉल की अनुक्रम है:
fetch-call
संकलक और समारोह के fetch
पता करने की जरूरत है तो यह call
।
जबकि आभासी कार्यों के मामले में अनुक्रम है:
fetch-fetch-call
संकलक this
से vptr
, तो fetch
vptr
से समारोह का पता और उसके बाद call
समारोह fetch
की जरूरत है।
यह एक सरल सरलीकरण है जो वास्तव में वास्तविक अनुक्रम से कहीं अधिक जटिल है, लेकिन आपको वास्तव में यह जानने की ज़रूरत है कि किसी को वास्तव में कार्यान्वयन nitty gritty के बारे में जानने की आवश्यकता नहीं है।
अच्छा पढ़ें:
वर्चुअल विधि को कॉल करते समय, इसे वर्चुअल फ़ंक्शन तालिका में कॉल करने के लिए कौन सा फ़ंक्शन देखना होगा।
तो वर्चुअल फ़ंक्शन और गैर वर्चुअल फ़ंक्शन को कॉल करने के बीच क्या अंतर है? उदाहरण के लिए, उनमें से प्रत्येक के लिए कितनी मेमोरी एक्सेस आवश्यक है? – cheng
@cheng: मुझे नहीं पता कि वर्चुअल विधि कॉल में गैर-वर्चुअल विधि कॉल की तुलना में कितनी अधिक पहुंच है (मैं एक या दो मानता हूं), लेकिन वर्चुअल विधि कॉल के लिए थोड़ा और काम करने की आवश्यकता होती है। – icktoofay
ठीक है, मैं इसे समझने की कोशिश करूंगा। धन्यवाद। – cheng
आप एक आधार वर्ग 'बेस' और व्युत्पन्न वर्ग 'व्युत्पन्न' है और आप एक समारोह है, तो 'समारोह()' बेस क्लास में आभासी रूप में परिभाषित किया। यह func व्युत्पन्न वर्ग द्वारा ओवरराइड किया गया है।
आप
Base obj = new Derived();
obj.func();
फिर व्युत्पन्न वर्ग की 'समारोह' कहा जाता है परिभाषित मान लीजिए।जबकि 'func()' को बेस में आभासी के रूप में परिभाषित नहीं किया गया था, तो इसे 'बेस' कक्षा से बुलाया जाएगा। यह अंतर है कि फ़ंक्शन कॉलिंग विटुअल और गैर वर्चुअल फ़ंक्शन
को कॉल करने के बाद चित्र में आ रहा है कुछ सूक्ष्म बिंदु: 1. 'obj' को एक सूचक होने की आवश्यकता है। 2. यह उल्लेख करने के लिए कि ओवरसीड फ़ंक्शन 'व्युत्पन्न :: func()' को 'बेस :: func() ' –
को ओवरराइड करने के लिए समान तर्क लेना चाहिए, यह एक सूक्ष्म बिंदु नहीं है, बल्कि एक महत्वपूर्ण है। "obj.func()" बेस क्लास विधि को कॉल नहीं करेगा लेकिन किसी को पॉइंटर्स का उपयोग करना होगा और वर्चुअल विधियों का उपयोग करने के लिए "obj-> func()" को कॉल करना होगा। – user463035818
ध्यान दें कि कोई पॉइंटर्स के बजाय संदर्भों का उपयोग कर सकता है, हालांकि हमेशा एक ही परिस्थितियों में नहीं। उदाहरण के लिए, किसी संदर्भ को किसी भिन्न ऑब्जेक्ट को संदर्भित करने के लिए रीबाउंड नहीं किया जा सकता है। – Alan
गैर वर्चुअल सदस्य फ़ंक्शंस को स्थिर रूप से हल किया गया है। सदस्य फ़ंक्शन ऑब्जेक्ट पर पॉइंटर (या संदर्भ) के प्रकार के आधार पर संकलित समय पर स्थिर रूप से बाध्यकारी हैं।
इसके विपरीत, आभासी सदस्य कार्य हैंरन-टाइम में गतिशील रूप से बाध्यकारी। यदि कक्षा में कम से कम एक वर्चुअल सदस्य फ़ंक्शन है तो संकलक ऑब्जेक्ट के निर्माण के दौरान vptr (वर्चुअल टेबल पता) नामक ऑब्जेक्ट में एक छुपा सूचक डालता है।
कंपाइलर प्रत्येक वर्ग के लिए एक v-table बनाता है जिसमें कम से कम एक वर्चुअल फ़ंक्शन होता है। वर्चुअल टेबल में वर्चुअल फ़ंक्शन का पता होता है। वर्चुअल फ़ंक्शन पॉइंटर के
वर्चुअल फ़ंक्शन के प्रेषण के दौरान सरणी या सूची (कंपाइलर पर निर्भर) हो सकती है, रन-टाइम सिस्टम ऑब्जेक्ट के वी-पॉइंटर (क्लास ऑब्जेक्ट से पता लाता है) कक्षा के वी- तालिका, फिर ऑफ़सेट बेस पता (vptr) में जोड़ा जाता है और फ़ंक्शन को कॉल करता है।
ऊपर तकनीक के अंतरिक्ष लागत वाली भूमि के ऊपर नाममात्र है: (लेकिन केवल वस्तुओं है कि गतिशील बाध्यकारी करने की आवश्यकता होगी के लिए) वस्तु प्रति एक अतिरिक्त सूचक, प्लस विधि के अनुसार एक अतिरिक्त सूचक (लेकिन केवल आभासी तरीकों के लिए) । समय-लागत ओवरहेड भी काफी नाममात्र है: सामान्य फ़ंक्शन कॉल की तुलना में, वर्चुअल फ़ंक्शन कॉल के लिए दो अतिरिक्त fetches (v-pointer का मान प्राप्त करने के लिए, विधि के पते को प्राप्त करने के लिए एक सेकंड) की आवश्यकता होती है। ।
इस रनटाइम गतिविधि में से कोई भी गैर वर्चुअल फ़ंक्शंस के साथ होता है, क्योंकि संकलक पॉइंटर के प्रकार के आधार पर संकलन-समय पर गैर वर्चुअल फ़ंक्शंस को हल करता है।
मैंने बेहतर तरीके से समझने के लिए सरल उदाहरण लिया है, कैसे बाध्यकारी गैर वर्चुअल फ़ंक्शन & वर्चुअल फ़ंक्शन और वर्चुअल फ़ंक्शन तंत्र कैसे काम करता है।
#include<iostream>
using namespace std;
class Base
{
public:
virtual void fun()
{}
virtual void fun1()
{}
void get()
{
cout<<"Base::get"<<endl;
}
void get1()
{
cout<<"Base::get1"<<endl;
}
};
class Derived :public Base
{
public:
void fun()
{
}
virtual void fun3(){}
void get()
{
cout<<"Derived::get"<<endl;
}
void get1()
{
cout<<"Derived::get1"<<endl;
}
};
int main()
{
Base *obj = new Derived();
obj->fun();
obj->get();
}
कैसे vtable बेस & के लिए बनाया व्युत्पन्न वर्ग
विधानसभा कोड बेहतर समझ के लिए उत्पन्न होता है।
$ g++ virtual.cpp -S -o virtual.s
मैं बेस के लिए virtual.s से vtable की जानकारी दिलवाया है और क्रमशः वर्ग व्युत्पन्न:
_ZTV4Base:
.quad _ZN4Base3funEv
.quad _ZN4Base4fun1Ev
_ZTV7Derived:
.quad _ZN7Derived3funEv
.quad _ZN4Base4fun1Ev
.quad _ZN7Derived4fun3Ev
आप मज़ा & fun1 बेस कक्षा में केवल दो आभासी कार्य हैं देख सकते हैं। बेस क्लास (_ZTV4Base) के Vtable में वर्चुअल फ़ंक्शन दोनों की प्रविष्टियां हैं। Vtable में गैर वर्चुअल फ़ंक्शन का प्रवेश नहीं है। कृपया मज़े के नाम से भ्रमित न हों (ZN4Base3funEv) & fun1 (ZN4Base4fun1Ev), उनका नाम उलझ गया।
व्युत्पन्न वर्ग vtable है पेड़ प्रविष्टियों
- मज़ा (_ZN7Derived3funEv) ओवरराइड समारोह
- fun1 (_ZN4Base4fun1Ev) व्युत्पन्न वर्ग में बेस वर्ग
- fun3 (_ZN7Derived4fun3Ev) नए कार्य से विरासत में मिली
गैर वर्चुअल फ़ंक्शन & वर्चुअल फ़ंक्शन कैसे कहा जाता है?
गैर आभासी समारोह
Derived d1;
d1.get();
subq $16, %rsp
leaq -16(%rbp), %rax
movq %rax, %rdi
call _ZN7DerivedC1Ev //call constructor
leaq -16(%rbp), %rax
movq %rax, %rdi
call _ZN7Derived3getEv //call get function
बस बता लाने और फोन मिल के लिए गैर आभासी समारोह
Base *obj = new Derived();
obj->fun();
pushq %rbx
subq $24, %rsp
movl $8, %edi
call _Znwm //call new to allocate memory
movq %rax, %rbx
movq $0, (%rbx)
movq %rbx, %rdi
call _ZN7DerivedC1Ev //call constructor
movq %rbx, -24(%rbp)
movq -24(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq -24(%rbp), %rdx
movq %rdx, %rdi
call *%rax //call fun
के लिए
(बंधन संकलन समय पर हुआ)
vptr लाएं, फ़ंक्शन जोड़ें ऑफसेट, फ़ंक्शन को कॉल
64 की सभा (बंधन रन समय में हुआ) C++ प्रोग्रामर के सबसे भ्रामक है, लेकिन यदि किसी भी चर्चा करना चाहते हैं तो आपका स्वागत है
एक गतिशील रूप से जुड़े मॉड्यूल में एक सामान्य फ़ंक्शन को कॉल करने में सूचक संकेत शामिल हो सकता है। – curiousguy
- 1. सी ++ आभासी फ़ंक्शन कॉल बनाम बूस्ट :: फ़ंक्शन कॉल speedwise
- 2. वर्चुअल फ़ंक्शन कॉन्स बनाम वर्चुअल फ़ंक्शन गैर-कॉन्स
- 3. फ़ंक्शन को कॉल करने और फ़ंक्शन का उदाहरण बनाने के बीच जावास्क्रिप्ट अंतर
- 4. फ़ंक्शन पॉइंटर बनाम फ़ंक्शन कॉल के बीच क्या अंतर है?
- 5. क्या कोई निजी और संरक्षित शुद्ध वर्चुअल फ़ंक्शन के बीच कोई अंतर है?
- 6. फ़ंक्शन "मेल()" और "@mail()" कॉल के बीच क्या अंतर है?
- 7. वर्चुअल फ़ंक्शन
- 8. इनलाइन फ़ंक्शन और स्थिर इनलाइन फ़ंक्शन के बीच अंतर
- 9. चेकबॉक्स पर क्लिक करने और '.click()' फ़ंक्शन को कॉल करने के बीच क्या अंतर है?
- 10. "फ़ंक्शन" और "फ़ंक्शन" के बीच क्या अंतर है! वीआईएम में?
- 11. कथन और फ़ंक्शन के बीच अंतर
- 12. फ़ंक्शन टेम्पलेट और टेम्पलेट फ़ंक्शन के बीच क्या अंतर है?
- 13. फ़ंक्शन और नए फ़ंक्शन के बीच जावास्क्रिप्ट अंतर
- 14. संदर्भ चर और वर्चुअल फ़ंक्शन
- 15. एक कॉन्स सदस्य फ़ंक्शन और गैर-कॉन्स्ट सदस्य फ़ंक्शन के बीच क्या अंतर है?
- 16. डायमंड विरासत और शुद्ध वर्चुअल फ़ंक्शन
- 17. वर्चुअल विधि को ओवरलोड करने से गैर-वर्चुअल विधि से भिन्न होता है?
- 18. पैरामीटर खराब अभ्यास के साथ गैर शुद्ध वर्चुअल फ़ंक्शन हैं?
- 19. सार्वजनिक वर्चुअल फ़ंक्शन C++
- 20. वर्चुअल फ़ंक्शन vptr
- 21. सी ++ आभासी फ़ंक्शन रिटर्न प्रकार
- 22. सी ++: व्युत्पन्न वर्ग के वर्चुअल फ़ंक्शन को कॉल करना
- 23. वर्चुअल फ़ंक्शन ने व्युत्पन्न कक्षा
- 24. फ़ंक्शन को बार-बार कॉल करने के लिए फ़ंक्शन?
- 25. क्या सी # जेनेरिक वर्चुअल फ़ंक्शन कॉल को विस्तारित करने के लिए उपयोग किया जा सकता है?
- 26. फ़ंक्शन ऑब्जेक्ट और कॉल करने योग्य ऑब्जेक्ट के बीच क्या अंतर है?
- 27. चर के लिए फ़ंक्शन असाइन करने के बीच अंतर या
- 28. क्लोजर फ़ंक्शन (एनटी [कॉल इंडेक्स]) और संरचना (अंतिम (इंडेक्स कॉल लेना) के बीच क्या अंतर है)
- 29. अमूर्त और आभासी के बीच क्या अंतर है?
- 30. फोर्स व्युत्पन्न वर्ग को बेस फ़ंक्शन कॉल करने के लिए
वास्तव में अपने प्रश्न क्या है? –
एक वर्चुअल फ़ंक्शन गतिशील प्रेषण से गुजरता है। इसे बेहतर सीखने के लिए आपको [एक अच्छी सी ++ पुस्तक] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) चुननी चाहिए। – GManNickG
मुझे लगता है कि सवाल थोड़ा अस्पष्ट है। इसका क्या मतलब है? कोड अर्थशास्त्र स्तर, कंपाइलर स्तर या मशीन स्तर पर अंतर? – erenon