2012-07-23 10 views
5

मैं अपने आवेदन समस्या में से एक पर काम कर रहा हूं। यहां जिस समस्या का सामना कर रहा हूं वह है कि फ़ंक्शन का कुछ गुच्छा है जिसे मुझे क्लास ऑब्जेक्ट के पॉइंटर का उपयोग करके कॉल करने की आवश्यकता है।सी ++ और उसके सदस्यों में किसी ऑब्जेक्ट का पता

लेकिन मुख्य समस्या यह है कि मेरे पास मेरे साथ क्लास पॉइंटर नहीं है, इसके बजाय मेरे पास एक सदस्य परिवर्तनीय मान है (मान लें कि इसकी मानों की एक सूची है)। इसके बाद मैंने नीचे दिए गए कोड के साथ एक छोटा परीक्षण किया।

using namespace std; 

class Person { 
public: 
     Person(string name, int age) { 
      this->name = name; 
      this->age = age; 
     } 
     string getName() { 
      return name; 
     } 
     int getAge() { 
      return age; 
     } 
     void Print() 
     { 
     printf("This address is %x\n",this); 
     printf("age adress is %x\n",&age); 

     } 
private: 
     int age; 
     string name; 

}; 

int main() { 
     cout << "Creating a person..." << endl; 

Person *johnDoe=new Person("John Doe", 25); 
     cout << "Person's name: " << johnDoe->getName() << endl; 
     cout << "Person's age: " << johnDoe->getAge() << endl; 
     johnDoe->Print(); 
     delete johnDoe; 
     return 0; 
} 

निष्पादन की coutput है:

> ./a.out 
Creating a person... 
Person's name: John Doe 
Person's age: 25 
This address is 72918 
age adress is 72918 

अब मेरी संदेह नहीं है:

यह गारंटी है कि वर्ग के सदस्य चर का पता हमेशा वस्तु का पता की ओर इशारा करता है? क्या मैं इस पते का उपयोग कर सकता हूं यदि मुझे अन्य कोर एपीआई फ़ंक्शंस को कॉल करने के लिए पॉइंटर का उपयोग करने की आवश्यकता है?

मैंने इसे देखा जब मैंने इसे देखा?

(C1x §6.7.2.1.13: "एक संरचना वस्तु के लिए एक सूचक, उपयुक्त रूप से परिवर्तित, अपनी प्रारंभिक सदस्य को इंगित करता है ... और इसके विपरीत संरचना वस्तु के रूप में, लेकिन नहीं पर भीतर अज्ञात गद्दी हो सकता है। इसकी शुरुआत। ")

यह सी ++ और कक्षाओं के मामले में भी सच है?

+1

मैक्रो ऑफसेट देखें। केवल पीओडी प्रकार के लिए! –

+0

प्रत्येक वर्ग प्रकार के लिए, प्रत्येक डेटा सदस्य निश्चित ऑफ़सेट मान पर होगा।यह ऑब्जेक्ट का प्रारंभिक पता नहीं है क्योंकि संकलक शीर्ष पर कुछ सामान रखता है। लेकिन यह अलग होगा जब आपके पास वर्चुअल फ़ंक्शंस हों क्योंकि कंपाइलर को ऑब्जेक्ट में vptr * को भी रखना होगा। इसलिए मैं इस तरह से करने के लिए आम तौर पर अच्छा अभ्यास नहीं करता हूं। – madu

+1

संबंधित हो सकता है: http://stackoverflow.com/questions/8240273/a-portable-way-to-calculate-pointer-to-the-whole-structure-using-pointer-to-a-fi – user396672

उत्तर

7

क्या यह गारंटी है कि कक्षा सदस्य चर का पता हमेशा वस्तु के पते पर इंगित करता है?

नहीं सी ++ में, पहले सदस्य (विशेष रूप से व्युत्पन्न कक्षाओं और पॉलिमॉर्फिक कक्षाओं के लिए) से पहले सामान है। कार्यान्वयन परिभाषित वास्तव में क्या है।

क्या मैं इस पते का उपयोग कर सकता हूं यदि मुझे अन्य कोर एपीआई फ़ंक्शंस को कॉल करने के लिए पॉइंटर का उपयोग करने की आवश्यकता है?

नहीं, और आपको इसकी आवश्यकता नहीं है: जब भी आपके पास सदस्यों तक पहुंच हो, तो आपके पास this तक पहुंच नहीं है, नहीं?

+0

दुर्भाग्य से नहीं। मेरे पास पेड़ के आखिरी पत्ते के लिए एक सूचक है, मेरे पास केवल मूल कुंजी है और माता-पिता की कुंजी का उपयोग करके मैं बच्चों की सूची प्राप्त कर सकता हूं, जिसमें यह एक सूची है और जो वर्ग का मेबर है। इसे एक के रूप में कहा जा सकता है। पेड़ लेकिन यह एक वास्तविक पेड़ कार्यान्वयन नहीं है। – Vijay

+0

@ पीटर यह अस्पष्ट है। लेकिन जवाब वही रहता है। आप * पॉइंटर-टू-सदस्य को कक्षा में पॉइंटर के रूप में उपयोग नहीं कर सकते हैं। ऐसा करने से अमान्य सी ++ कोड होता है जो टूट जाएगा। –

1

कक्षाओं के लिए यह भी सच है जब तक कि उनके पास कोई वर्चुअल फ़ंक्शन न हो। अगर आपको विरासत है तो आपको भी ध्यान रखना चाहिए (सुनिश्चित नहीं है कि नियम वास्तव में कैसे हैं)।

सामान्यतः, यह एक बुरा विचार है हालांकि। तुम ऐसा क्यों करना चाहते हो। आप कक्षा की संरचना पर भरोसा करते हैं (यानी आपका कोड तोड़ देगा यदि आप दुर्घटना से उम्र से पहले एक सदस्य जोड़ते हैं) और आप encapsulation (किसी भी अन्य वर्ग को उम्र के लिए सूचक होना चाहिए, क्योंकि यह निजी है - आप लीक करेंगे वस्तु प्रतिनिधित्व)।

बीटीडब्ल्यू: क्या आप जावा प्रोग्रामर हैं? आपका कन्स्ट्रक्टर आपके जैसा दिखता है, क्योंकि आप अपनी ऑब्जेक्ट को सही तरीके से प्रारंभ नहीं करते हैं। आप इसे इस तरह करना चाहिए:

Person(String n, int a) : age(a), name(s) {} 

(अन्यथा संकलक पहले पूर्णांक और स्ट्रिंग के डिफ़ॉल्ट contstructors कॉल करेंगे और उसके बाद = ऑपरेटर फोन उन पर - यह कुशल नहीं है)।

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