2012-02-23 17 views
25

फ़ाइल आहसी ++ अपरिभाषित संदर्भ vtable करने और विरासत

#ifndef A_H_ 
#define A_H_ 

class A { 
public: 
    virtual ~A(); 
    virtual void doWork(); 
}; 

#endif 

फ़ाइल Child.h

#ifndef CHILD_H_ 
#define CHILD_H_ 

#include "A.h" 

class Child: public A { 
private: 
    int x,y; 
public: 
    Child(); 
    ~Child(); 
    void doWork(); 
}; 
#endif 

और Child.cpp

#include "Child.h" 

Child::Child(){ 
    x = 5; 
} 

Child::~Child(){...} 

void Child::doWork(){...}; 

संकलक का कहना है एक अपरिभाषित संदर्भ है कि वहाँ A के लिए vtable करने के लिए। मैंने कई अलग-अलग चीजों की कोशिश की है और अभी तक कोई भी काम नहीं किया है।

मेरा उद्देश्य इंटरफेस होने के लिए कक्षा A के लिए है, और हेडर से कार्यान्वयन कोड अलग करने के लिए है।

+4

आपको घोषित किए गए प्रत्येक गैर-शुद्ध वर्चुअल फ़ंक्शन को परिभाषित करना होगा। आपको एक गैर-वर्चुअल फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं है जिसे आप घोषित करते हैं लेकिन उपयोग नहीं करते हैं। –

उत्तर

60

त्रुटि & यह कैसे हल करें?

आप class A में सभी आभासी कार्यों के लिए definitions प्रदान करने के लिए की जरूरत है। केवल शुद्ध आभासी कार्यों की कोई परिभाषा नहीं है।

अर्थात्:

virtual ~A(); 
virtual void doWork(); 

परिभाषित किया जाना चाहिए (एक शरीर होना चाहिए)

जैसे::

A.cpp

void A::doWork() 
{ 
} 
A::~A() 
{ 
} 

class A दोनों तरीकों में

चेतावनी:
यदि आप अपने class A एक अंतरफलक के रूप में कार्य करना चाहते हैं (Abstract class सी में ++ a.k.a) तो आप विधि शुद्ध आभासी बनाना चाहिए।

virtual void doWork() = 0; 

अच्छा पढ़ें:

What does it mean that the "virtual table" is an unresolved external?
When building C++, the linker says my constructors, destructors or virtual tables are undefined.

+0

आपका क्या मतलब है? – rjmarques

+0

@ user1227351: बेहतर व्याख्या करने के लिए उत्तर अपडेट किया गया। आगे स्पष्टीकरण के लिए लिंक पढ़ें। –

+0

आभासी ~ ए() होने के बाद; आभासी शून्य doWork() = 0; अभी भी vtable त्रुटि =/देता है। लेकिन विनाशक के बिना यह ठीक काम करता है। हालांकि इसके बिना, अगर मैं कुछ ऐसा करता हूं: ए * ए = नया बच्चा(); एक हटाएं; जाहिर है यह चाइल्ड :: ~ चाइल्ड() को कॉल नहीं करेगा। क्या आसपास कोई काम है? – rjmarques

6

मेरे उद्देश्य एक एक अंतरफलक है, और हेडर से कार्यान्वयन कोड अलग करने के लिए है।

उस मामले में,

class A { 
    // ... 
    virtual void doWork() = 0; 
}; 
+0

अगर मैं विनाशक को भी हटा देता हूं तो त्रुटि को हटा देता है। उस स्थिति में यदि मैं करता हूं: ए = नया बच्चा(); एक हटाएं; क्या विनाशक इसे कॉल करेगा? – rjmarques

+0

विनाश हमेशा निर्माण के विपरीत क्रम में है। इस मामले में, कक्षा 'ए' विनाशक आभासी होना चाहिए जो 'चाइल्ड' विनाशक को पहले 'ए' विनाशक के बाद बुलाया जाता है। यदि 'ए' वर्ग विनाशक आभासी नहीं है तो व्यवहार अपरिभाषित है। – Mahesh

+0

यह बच्चे के विनाशक को कॉल करेगा क्योंकि आपने अभिभावक वर्ग विनाशक वर्चुअल बनाया है। उसके बाद, अभिभावक वर्ग के विनाशक। – Izza

1

यदि अन्य प्रतिक्रियाओं में से कोई भी आपकी मदद के लिए किसी भी "* .gch" फ़ाइलें हटाने की सुनिश्चित करें कि सदस्य समारोह के रूप में शुद्ध वर्ग ए में आभासी बनाते हैं।

संबंधित मुद्दे