2010-07-19 5 views
12

क्या सी में कभी परिभाषित संरचनाओं में कोई लाभ नहीं है? SQLite स्रोत कोड मेंकभी परिभाषित संरचना

उदाहरण:

/* struct sqlite3_stmt is never defined */ 
typedef struct sqlite3_stmt sqlite3_stmt; 

और वस्तु इतनी तरह चालाकी से किया जाता है:

typedef struct Vdbe Vdbe; 
struct Vdbe { 
    /* lots of members */ 
}; 


int sqlite3_step(sqlite3_stmt *pStmt) { 
    Vdbe *v = (Vdbe*) pStmt; 
    /* do stuff with v... */ 
} 

तो क्यों सिर्फ वास्तविक संरचना निजी तौर पर foo.c में परिभाषित के साथ, एक सामान्य सार प्रकार का उपयोग नहीं foo.h हेडर में स्रोत और सार्वजनिक typedef?

+1

कोई अच्छा कारण नहीं है। लेकिन बहुत से लोग बड़ी, प्रसिद्ध परियोजनाओं में भी सी में बहुत सी बेवकूफ चीजें करते हैं। –

+7

आर के लिए: आप इस तरह के एक बर्खास्तगी रवैया के साथ बहुत दूर नहीं मिलेगा। स्क्लाइट एक प्रसिद्ध परिपक्व परियोजना है जो इसकी गुणवत्ता के लिए प्रतिष्ठित है। ऐसा लगता है कि डी। रिचर्ड हिप्प जानता है कि वह कोड के साथ क्या कर रहा है। –

उत्तर

9

स्पष्ट करने के लिए: क्या आप पूछ रहे हैं यही कारण है कि SQLite बजाय ऐसा करने का ऊपर करता है:

हैडर फ़ाइल:

typedef struct sqlite3_stmt sqlite3_stmt; 

सी फ़ाइल:

struct sqlite3_stmt { 
    /* lots of members */ 
}; 


int sqlite3_step(sqlite3_stmt *pStmt) { 
    /* do stuff with pStmt... */ 
} 

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

एकमात्र अच्छा - नाम शायद साथ कार्यान्वयन से संबंधित कुछ मतलब है

बैकएंड कोड, मैं अटकलें हूँ, एपीआई से पहले आया था और नाम Vdbe प्रयोग किया है: कारण मैं क्यों SQLite यह क्या करता है के बारे में सोच सकते हैं निम्नलिखित है "आभासी डेटाबेस प्रविष्टि" की रेखाएं (यहां जंगली अनुमान लगाएं)।

जब एपीआई बनाने के लिए समय आया, तो किसी को एहसास हुआ कि sqlite3_step द्वारा आवश्यक पैरामीटर Vdbe था लेकिन यह बिल्कुल ऐसा नाम नहीं था जो एपीआई के उपयोगकर्ता को बहुत कुछ बताए। इसलिए, उपयोगकर्ता के दृष्टिकोण से, Vdbe को sqlite3_stmt के रूप में जाना जाता है।

यहां मुद्दा यह है, तो, एक ही आइटम के दो विचारों के बीच अंतर करने के लिए है: बैकएंड Vdbe रों के मामले (जो वे कर रहे हैं) में सोचता है, क्योंकि वह एक ऐसा नाम है कार्यान्वयन के संदर्भ में समझ में आता है है। एपीआई sqlite3_stmt एस के बारे में बात करता है क्योंकि यह एक ऐसा नाम है जो इंटरफ़ेस के संदर्भ में समझ में आता है।

संपादित करें: जैसा कि अमरघोश बताते हैं, वही प्रभाव प्राप्त करने के लिए ऐसा क्यों न करें?

typedef struct Vdbe sqlite3_stmt; 

KennyTM points out a good possible reason (कृपया उसे वोट अप, मैं यहाँ अपने प्रतिनिधि बंद साइफन नहीं करना चाहती): VDBE कई संभव बैकएण्ड का केवल एक ही है, इंटरफ़ेस "जेनेरिक" sqlite3_stmt का उपयोग करता है, और उसके बाद इसे लागू करने के लिए बैकएंड का उपयोग करने के लिए जो कुछ भी उपयोग किया जाता है।

+4

फिर क्यों वे 'टाइप' टाइप नहीं करते हैं Vdbe sqlite3_stmt; ' – Amarghosh

+0

आपको यह सही मिला, यही वह है जो मैं पूछ रहा था। मुझे एक ही आइटम के दो विचारों का विचार पसंद है। (और, वैसे, यह SQLite की मेरी समझ है कि वीडीबीई "वर्चुअल डेटाबेस इंजन" के लिए खड़ा है) – Axel

+0

@ आर्मघोश: अच्छा बिंदु ... केनीटीएम का संपादित उत्तर एक अच्छा संभावित कारण प्रदान करता है (कि वीडीबीई कई बैकएंडों में से एक है) –

15

यह उपयोगकर्ता से sqlite3_stmt के कार्यान्वयन विवरण को छिपाने के लिए इस तरह परिभाषित किया गया है, इस प्रकार आंतरिक राज्यों को गड़बड़ होने से बचाता है। Opaque pointer देखें।

(यह भी मजबूर करता उपयोगकर्ता केवल संरचना sqlite3_stmt ही अधूरा कार्यान्वयन के बाद से एक सूचक के रूप में प्रकार का उपयोग करने।)


संपादित करें: VDBE (आभासी डेटाबेस इंजन) बस है "एक" पीठ SQLite3 एपीआई का अंत। मेरा मानना ​​है कि बैक-एंड बदल सकता है, इस प्रकार sqlite3_stmt* आवश्यक नहीं है Vdbe*। एपीआई में Vdbe* का खुलासा नहीं करना क्योंकि बैक-एंड विवरण का खुलासा नहीं किया जाना चाहिए।

+2

फिर भी, ओपेक पॉइंटर लेख के उदाहरण में, 'struct cat_t' को परिभाषित किया गया है ... क्या 'struct sqlite3_stmt' केवल' struct Vdbe' पर कार्यान्वयन को छिपाने के लिए उपयोग किया जाता है? फिर, क्या 'Vdbe' पर ओपेक पॉइंटर पैटर्न का उपयोग न करने का कोई कारण है? – Axel

+0

+1 "मुझे विश्वास है कि बैक-एंड बदल सकता है" एक बहुत ही व्यावहारिक कारण की तरह लगता है! –

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