2013-02-20 103 views
5

के साथ अजीब बग सबसे पहले, अगर उत्तर स्पष्ट है तो मैं पहले से माफ़ी मांगना चाहता हूं; मैं सी ++ के लिए बहुत नया हूं और मेरी पहली भाषा जावा है। मैं स्टैक ओवरफ्लो के लिए भी नया हूं, इसलिए यदि मेरे प्रश्न में कुछ गड़बड़ है या आपको कुछ और चाहिए, तो कृपया मुझे बताएं।डिफ़ॉल्ट कन्स्ट्रक्टर (सी ++)

तो। मैं यहाँ कोड के इस टुकड़े है:

Ball::Ball() { 

    // This ugly thing calls the full constructor with a random x and y position 
    // in such a way the the entire ball is inside the screen. 

    Ball::Ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS); 

} 
Ball::Ball(float x, float y) { 

    loc.x = x; 
    loc.y = y; 

    ball.setPosition(loc.x - BALL_RADIUS, loc.y - BALL_RADIUS); 
    ball.setRadius(BALL_RADIUS); 
    ball.setFillColor(sf::Color::Red); 
    ball.setOutlineColor(sf::Color::Black); 
    ball.setOutlineThickness(1); 

} 

(मैं वेक्टर और CircleShape के लिए SFML उपयोग कर रहा हूँ) और यहाँ है हैडर (ऊपर फाइल में #included):

class Ball { 

private: 
    sf::CircleShape ball; 
    sf::Vector2f loc; 
    sf::Vector2f vel; 
    sf::Vector2f acc; 

    void update(); 
    void bounce(); 
    void draw(); 

public: 
    Ball(); 
    Ball(float x, float y); 
    void run(); 

}; 

जब मैं

Ball ball; 

(और हाँ, सभी एसएफएमएल प्रतिपादन सामग्री काम करता है) के साथ गेंद बनाएं, यह कभी नहीं दिखाता है। कुछ जांच से पता चलता है कि इसका loc.x और loc.y चर सेट नहीं हैं, और शायद, न ही गेंद ऑब्जेक्ट का त्रिज्या, fillcolor, आदि हैं। यदि मैं इनके मानों को std :: cout के अंदर कन्स्ट्रक्टर, loc.x और loc.y और अन्य सभी सेट के साथ मानों को प्रिंट करता हूं, तो मुझे लगता है कि वे कन्स्ट्रक्टर के बाद कहीं भी अनसेट हो जाते हैं। क्या अजीब बात है कि अगर मैं

Ball ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS); 

या यहाँ तक कि

Ball ball(400, 300); 

सब कुछ के साथ गेंद को बनाने के लिए पूरी तरह से काम करता है, और गेंद के लिए स्क्रीन पर दिखाई दें। मैं वास्तव में स्टंप लोगों हूँ। अगर कोई मेरी मदद कर सकता है, तो यह बहुत अच्छा होगा।

बीटीडब्ल्यू, मैं एक्सकोड 4.5.2 के साथ ओएस एक्स 10.8 चला रहा हूं, और एसएफएमएल आरसी 2.0 का उपयोग कर रहा हूं, अगर इससे कोई फर्क पड़ता है।

धन्यवाद,

मैट

+0

इतनी जल्दी प्रतिक्रिया देने के लिए सभी को धन्यवाद! मैं दोनों रचनाकारों द्वारा बुलाए गए एक init() फ़ंक्शन का निर्माण करूंगा, जैसा कि ऐसा करने का सबसे अच्छा तरीका है जो मैं करना चाहता हूं। जावा से सी ++ में जाने से हेला भ्रमित है। – SlEePlEs5

उत्तर

2

निर्माता श्रृंखलन C++ समर्थित नहीं है इससे पहले कि सी ++ 11

आप एक समारोह के लिए तर्क लेते हैं और इसे दोनों निर्माता से कॉल कर सकते हैं। कुछ ऐसा:

Ball::Ball() { 

    // This ugly thing calls the full constructor with a random x and y position 
    // in such a way the the entire ball is inside the screen. 

    init((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS); 

} 

Ball::Ball(float x, float y) { 

    init(x,y); 

} 

Ball::init(float x, float y) { 

    loc.x = x; 
    loc.y = y; 

    ball.setPosition(loc.x - BALL_RADIUS, loc.y - BALL_RADIUS); 
    ball.setRadius(BALL_RADIUS); 
    ball.setFillColor(sf::Color::Red); 
    ball.setOutlineColor(sf::Color::Black); 
    ball.setOutlineThickness(1); 

} 
2

निर्माता श्रृंखलन सी में समर्थित नहीं है ++ जब तक आप सी ++ 11 जो मुझे लगता है कि आप नहीं कर रहे हैं का उपयोग कर रहे हैं।

LINK

3

निर्माता सी ++ में चेनिंग अनुमति नहीं है, बजाय, यहाँ क्या हो रहा हो जाएगा कि अपने वर्ग के एक अस्थायी संस्करण बनाया जाएगा, नहीं सौंपा: जानकारी के लिए इस सवाल का जवाब में

देखो कहीं भी, तो त्याग दिया।

इसके बजाए, इच्छित पैरामीटर के साथ एक निजी प्रारंभिक विधि बनाएं और इसे अपने पैरामीटर से सही पैरामीटर के साथ कॉल करें।

+1

+1 इस बात का जिक्र करने के लिए कि प्रश्न में सिंटैक्स क्या है, यह बताते हुए कि यह कैसे काम करता है। –

+0

डाउनवॉटर के लिए: 1) क्यों, 2) धन्यवाद, आपने अभी तक एक गैर-राउंड प्रतिनिधि होने की अपनी आजीवन जलन ठीक कर ली है और इस तरह मुझे इसे किसी और को नीचे खींचने से बचा लिया है। – slugonamission

+0

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

1

मैं कन्स्ट्रक्टर चेनिंग करने के बजाय सुझाव दूंगा, कि आप दो चरण प्रारंभिकरण का उपयोग करें, जिसका अर्थ यह होगा कि आप init() फ़ंक्शन बनाते हैं जिसे आप अपने डिफ़ॉल्ट कन्स्ट्रक्टर में कॉल करते हैं।

6

सी ++ 11 से पहले किसी अन्य निर्माता (जिसे कन्स्ट्रक्टर को प्रतिनिधि के रूप में जाना जाता है) से एक कन्स्ट्रक्टर को कॉल करना असंभव था।

Ball::Ball() 
: Ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, 
     (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS) 
{ } 

पूर्व सी ++ 11, यदि आप किसी अन्य समारोह है कि आम काम करता है बना सकते हैं और दोनों निर्माताओं मिल इसे कहते हैं: सी ++ 11 में यह करने के लिए, आप सदस्य initialisation सूची का उपयोग करने की जरूरत है।

Ball::Ball() { 
    init((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, 
     (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS); 
} 

Ball::Ball(float x, float y) { 
    init(x, y); 
} 

void Ball::init(float x, float y) { 
    loc.x = x; 
    loc.y = y; 

    ball.setPosition(loc.x - BALL_RADIUS, loc.y - BALL_RADIUS); 
    ball.setRadius(BALL_RADIUS); 
    ball.setFillColor(sf::Color::Red); 
    ball.setOutlineColor(sf::Color::Black); 
    ball.setOutlineThickness(1); 
} 
+1

एक 'init' फ़ंक्शन के बजाय, जो थोड़ा बदसूरत है और दो चरण निर्माण के लिए नौसिखिया की ओर जाता है, एक उप-ऑब्जेक्ट पर विचार करें: या तो डेटा सदस्य या बेस क्लास (इससे कोई फर्क नहीं पड़ता) –

+0

@Alf: अगर init() निजी है, वह समाधान बिल्कुल बुरा नहीं है। – aggsol

0

आपको एक init() विधि बनाना चाहिए और इसे अपने दोनों रचनाकारों में कॉल करना चाहिए।

Ball::Ball((rand() % (WINDOW_X - (2 * BALL_RADIUS))) + BALL_RADIUS, (rand() % (WINDOW_Y - (2 * BALL_RADIUS))) + BALL_RADIUS); 

एक अस्थायी गेंद वस्तु बनाता है और इसे तुरंत नष्ट कर देता है

1

अन्य उत्तर यह करने के लिए वाक्य रचनात्मक रूप से सही तरीका देते हैं।

मैं शब्दार्थ सही कुछ बनाना होगा ताकि आप इसे के रूप में तो कहते हैं:

class Ball { 
public: 
    //... 
    static Ball createRandom(); 
}; 

के रूप में कार्यान्वित:

int randomisePosition(int position) { 
    return (rand() % (position - (2 * BALL_RADIUS))) + BALL_RADIUS; 
} 

Ball Ball::createRandom() { 
    return Ball(randomisePosition(WINDOW_X), 
       randomisePosition(WINDOW_Y)); 
} 

Ball ball = Ball::createRandom(); 

आप Ball के static समारोह के रूप में createRandom लागू

+0

+1 कोड को अंधेरे से मालिश करने की कोशिश न करने के बजाय, बल्कि उपयोगकर्ता को क्या चाहिए इसकी सोचने के लिए। –

+0

धन्यवाद। मैं कोशिश करूँगा। प्रश्नों का उत्तर देने का हमेशा सही तरीका नहीं है, और हमेशा ऊपर उठता नहीं है, लेकिन मैं सबसे अच्छा एकल जवाब होने की कोशिश नहीं कर रहा हूं। मैं संदर्भ का विस्तार करना चाहता हूं। –

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

  • कोई संबंधित समस्या नहीं^_^