2010-11-24 15 views
16

के लिए अनिर्धारित संदर्भ मैं सी ++ सीख रहा हूं। मैं एक अभ्यास करने की कोशिश कर रहा हूं जहां मैं एक शुद्ध वर्चुअल क्लास के एक कार्यान्वयन के साथ कई कार्यान्वयन को परिभाषित करता हूं। मुझे कक्षा को जोड़ने में परेशानी हो रही है जो इन कार्यान्वयन का उपयोग करती है।सी ++ vtable

==> BasicMath.h <== 
#ifndef BASIC_MATH_H 
#define BASIC_MATH_H 

#include<string> 
#include<vector>  

class BasicMath { }; 


#endif // BASIC_MATH_H 

==> Operation.h <== 

#ifndef OPERATION 
#define OPERATION 

#include<string> 
#include<vector>  

class Operation { 
public: 
    virtual void perform(std::vector<std::string> vec) = 0; 
}; 


#endif // OPERATION 

==> Sum.h <== 
#ifndef SUM_H 
#define SUM_H 

#include "Operation.h" 

class Sum: public Operation { 
public: 
    void perform(std::vector<std::string> vec); 
}; 

#endif // SUM_H 

==> BasicMath.cpp <== 
#ifndef BASIC_MATH_C 
#define BASIC_MATH_C 

#include <string> 
#include <vector> 
#include <iostream> 
#include "BasicMath.h" 
#include "Sum.h" 

int main(int argc, char* argv[]) { 
    Sum op; 
} 

#endif // BASIC_MATH_C 

==> Sum.cpp <== 
#ifndef SUM_C 
#define SUM_C 

#include <vector> 
#include <string> 
#include <iostream> 
#include "Sum.h" 

void Sum::perform(std::vector<std::string> vec) { 
    using namespace std; 
    int total = 0; 
    cout << "Total: " << total << "\n"; 
}; 

#endif // SUM_C 

संकलन:

$ g++ -c Sum.cpp 
$ g++ -o BasicMath BasicMath.cpp 
/tmp/cc1VXjNl.o:BasicMath.cpp:(.text$_ZN3SumC1Ev[Sum::Sum()]+0x16): undefined reference to `vtable for Sum' 
collect2: ld returned 1 exit status 

मैं मैं यहाँ कम से कम एक मूर्ख बात कर रहा हूँ 95% यकीन है - लेकिन मेरे दिमाग मुझे क्या बताने के लिए मना कर रहा है।

मुझे this प्रश्न है लेकिन मेरी समस्या को ठीक करने में कामयाब नहीं रहा है।

+1

साइड नोट: आप निश्चित रूप से मूल्य से नहीं, संदर्भ द्वारा std :: वेक्टर पास करना चाहते हैं। – EboMike

+0

साइड नोट 2: आभासी कार्यों वाले वर्गों में आभासी विनाशक होना चाहिए। – EboMike

+0

मैंने g ++ टैग जोड़ा है, क्योंकि आपकी समस्या ऑब्जेक्ट फ़ाइलों को लिंक करने के लिए कंपाइलर (अधिक सटीक लिंकर) कैसे प्राप्त करें, और यह संकलक निर्भर है। –

उत्तर

16

आप अपने संकलन & लिंक लाइन (दूसरा जी ++ उपयोग) पर Sum.o ऑब्जेक्ट फ़ाइल शामिल नहीं कर रहे हैं।

+0

ठीक है कि यह बेहद आसान था। धन्यवाद नूह। रेफरी आदि द्वारा पास के बारे में अन्य बिंदुएं लें। मैं उस पर फिर से काम करूंगा, मैं इस त्रुटि को दूर कर रहा हूं। जी ++ मैनुअल पढ़ने की सूची पर चला जाता है! – Ben

+0

सही, मैं एक शामिल वर्ग की 'cpp' फ़ाइल संकलित नहीं कर रहा था। – zpon

1

आप Sum.cpp के बिना BasicMath.cpp को संकलित कर रहे हैं - आपके लिंकर को Sum.cpp के बारे में कोई जानकारी नहीं है। आपको एक साथ दोनों को संकलित करने की आवश्यकता होगी, यानी Sum.cpp BasicMath.cpp एक बार में, या आप .cpp फ़ाइलों को स्वतंत्र रूप से संकलित कर सकते हैं और फिर .o फ़ाइलों दोनों के साथ g ++ को कॉल करके निष्पादन योग्य बना सकते हैं।

5

कुछ लोगों ने पहले ही देखी गई समस्या का समाधान इंगित कर दिया है।

मैं कुछ अलग जोड़ दूंगा। आपको केवल अपने शीर्षकों में हेडर गार्ड की आवश्यकता है। आपने उन्हें स्रोत फ़ाइलों में भी शामिल किया है, जहां वे वास्तव में समझ में नहीं आते हैं। उदाहरण के लिए, मैं लाइनों तुम सच में sum.cpp में की जरूरत नहीं है (या यहाँ तक चाहते हैं) बाहर टिप्पणी की है:

//#ifndef SUM_C 
//#define SUM_C 
// 
#include <vector> 
#include <string> 
#include <iostream> 
#include "Sum.h" 

void Sum::perform(std::vector<std::string> vec) { 
    using namespace std; 
    int total = 0; 
    cout << "Total: " << total << "\n"; 
}; 

//#endif // SUM_C 

बस Fwiw, perform के बजाय, मैं प्रयोग करेंगे operator():

class Operation { 
public: 
    virtual void operator()(std::vector<std::string> vec) = 0; 
}; 

और (जाहिर है) यह भी है कि आप Sum के लिए अधिभारित करेंगे।

Sum op; 
op.perform(); 

आप की तरह कुछ का उपयोग करेंगे:: यह की तरह कुछ करने के बजाय का उपयोग करने के लिए,

Sum op; 
op(); 

यह विशेष रूप से सुविधाजनक है जब आप दूसरों के साथ अपने वर्ग गठबंधन है (उदाहरण के लिए, मानक पुस्तकालय में उन) जो कार्यों जैसे कार्यों का आह्वान करता है, चाहे वे वास्तव में कार्य कर रहे हों, या "मज़ेदार" (इस तरह की कक्षाएं, जो operator() अधिभारित करती हैं, इसलिए वाक्य रचनात्मक रूप से उन्हें लगभग कार्यों की तरह उपयोग किया जा सकता है)।

+0

हाय जैरी - मैंने कुछ एसीई कोड की समीक्षा करने के बाद मेरे स्रोत में गार्ड जोड़े, जिनके पास यह शैली http://www.cs.wustl.edu/~schmidt/ACE.html थी। शायद यह कुछ ढांचे के लिए आवश्यक है या अभी निष्क्रिय है? – Ben

1

मैं सामान्य रूप से इस त्रुटि का सामना करता हूं जब मैं गलती से =0 को शुद्ध वर्चुअल क्लास में अपने कार्यों में से किसी एक के अंत में भूल जाता हूं।

+0

इसका इसके साथ कुछ लेना देना नहीं है। = 0 का मतलब है कि आपकी कक्षा अमूर्त होगी। मुझे लगता है कि समस्या यह है कि आप एक फ़ंक्शन बॉडी लिखना भूल गए हैं। – EboMike

+0

धन्यवाद, इस जवाब ने मेरी मदद की। – maharvey67

19

मुझे बस एक ही समस्या का सामना करना पड़ा, लेकिन मेरी समस्या यह थी कि मैंने अपनी .cpp फ़ाइल को विनाशक कोडिन नहीं लिखा था।

class.h:

class MyClass { 
public: 
    MyClass(); 
    virtual ~MyClass(); 
}; 

वर्ग।सीपीपी:

MyClass::MyClass() {} 

यह मुझे केवल vtable त्रुटि संदेश देता है, और (खाली) विनाशक को लागू करने से समस्या हल हो जाती है।

[संपादित करें] इस प्रकार, सही किया वर्ग फ़ाइल इस तरह दिखता है:

MyClass::MyClass() {} 
MyClass::~MyClass() {} 
+3

जाहिर है, यह काफी आम हो सकता है। +1 ... इससे मुझे एक ही समस्या को हल करने में मदद मिली। – IAbstract

+0

दूसरा कोड ब्लॉक "खाली (विनाशक) विनाशक को लागू नहीं कर रहा है" जैसा कि आप कहते हैं, यह निर्माता को कार्यान्वित कर रहा है। – DBedrenko

+1

दूसरा कोड ब्लॉक जानबूझकर उस राज्य को प्रदर्शित करता है जिसने त्रुटि उत्पन्न की। मैंने सोचा कि वाक्य बाद में समाधान के लिए पर्याप्त होगा लेकिन मैंने "सही" सामग्री को जोड़ा। –

3

कि त्रुटि भी अगर आप शुद्ध आभासी कार्यों

त्रुटि के लिए = 0 भूलना होता है:

class Base { 
    public: 
     virtual void f(); 
}; 

class Derived : public Base { 
    public: 
     virtual void f() {} 
}; 

int main() { 
    Derived d; 
    Base *b = &d; 
} 

कोई त्रुटि नहीं:

class Base { 
    public: 
     virtual void f() = 0; 
}; 

ऐसा इसलिए है क्योंकि = 0 के बिना, सी ++ यह नहीं जानता कि यह एक शुद्ध वर्चुअल फ़ंक्शन है, इसे बाद में परिभाषा की अपेक्षा करते हुए घोषणा के रूप में माना जाता है।

g++ 5.2.1 पर परीक्षण किया गया।

+1

लड़का आप मेरी जिंदगी एक्सडी बचाओ – vivi

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