2013-02-20 37 views
5

Trước hết, tôi muốn xin lỗi trước nếu câu trả lời là hiển nhiên; Tôi rất mới với C++ và ngôn ngữ đầu tiên của tôi là Java. Tôi cũng mới vào Stack Overflow, vì vậy nếu có điều gì đó sai với câu hỏi của tôi hoặc bạn cần bất cứ điều gì khác, xin vui lòng cho tôi biết.Lỗi lạ với hàm tạo mặc định (C++)

So. Tôi có đoạn mã này ở đây: (Tôi đang sử dụng SFML cho vector và CircleShape)

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); 

} 

Và đây là tiêu đề (#included vào file trên):

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(); 

}; 

Khi tôi tạo bóng với

Ball ball; 

(và có, tất cả công cụ hiển thị SFML hoạt động), nó không bao giờ hiển thị. Một chút điều tra cho thấy các biến loc.x và loc.y của nó không được thiết lập, và có lẽ, không phải là bán kính, tô màu, vv của đối tượng bóng. Nếu tôi in các giá trị của chúng với std :: cout bên trong hàm tạo, loc.x và loc.y và tất cả các số khác , vì vậy tôi giả định rằng chúng bị bỏ đặt ở đâu đó sau hàm tạo. Có gì là lạ là nếu tôi có thể tạo bóng bằng

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

hoặc thậm chí

Ball ball(400, 300); 

tất cả mọi thứ hoạt động hoàn hảo, và bóng xuất hiện trên màn hình. Tôi thực sự là những kẻ bối rối. Nếu có ai có thể giúp tôi, điều đó thật tuyệt.

BTW, tôi đang chạy OS X 10.8 với Xcode 4.5.2 và sử dụng SFML RC2.0, nếu điều đó tạo ra bất kỳ sự khác biệt nào.

Cảm ơn,

Matt

+0

Cảm ơn mọi người đã trả lời nhanh quá! Tôi sẽ tạo ra một hàm init() được gọi bởi cả hai hàm tạo, vì nó dường như là cách tốt nhất để làm những gì tôi muốn làm. Di chuyển từ Java sang C++ là hella khó hiểu. – SlEePlEs5

Trả lời

2

Constructor Chaining không được hỗ trợ trong C++ trước 11

C++

Bạn có thể lấy logic để một hàm và gọi nó từ cả hai constructor. một cái gì đó như:

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

Constructor Chaining không được hỗ trợ trong C++, trừ khi bạn đang sử dụng C++ 11 mà tôi giả sử bạn thì không.

Nhìn vào câu trả lời này để biết chi tiết:

LINK

3

Constructor chaining trong C++ không được phép, thay vào đó, điều gì sẽ xảy ra ở đây là một phiên bản tạm thời của lớp học của bạn sẽ được tạo ra, không được gán bất cứ nơi nào, sau đó bị loại bỏ.

Thay vào đó, hãy tạo phương thức khởi tạo riêng với các tham số bạn muốn và gọi từ các hàm tạo của bạn với các tham số chính xác.

+1

+1 Để đề cập đến cú pháp trong câu hỏi, thay vì chỉ nói cách làm cho nó hoạt động. –

+0

Để downvoter: 1) tại sao, 2) cảm ơn, bạn chỉ chữa khỏi sự kích thích suốt đời của tôi có một đại diện không tròn và do đó đã cứu tôi từ downvoting một người nào khác để làm tròn nó đi. – slugonamission

+0

Tôi không bỏ phiếu, nhưng việc xây dựng chuỗi/phái đoàn hiện được cho phép/có thể. Một số người chỉ cực kỳ quan trọng. – aggsol

1

Tôi sẽ đề xuất thay vì tạo chuỗi hàm tạo, bạn sử dụng khởi tạo hai giai đoạn, điều đó có nghĩa là bạn tạo hàm init() mà bạn gọi trong hàm dựng mặc định của mình.

6

Gọi một hàm tạo từ một hàm tạo khác (được gọi là ủy nhiệm một hàm dựng) là không thể trước C++ 11. Để làm điều đó trong C++ 11, bạn cần phải sử dụng các thành viên danh sách khởi động:

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

Pre-C++ 11, bạn có thể tạo ra một chức năng để làm công việc phổ biến và có được cả hai nhà xây dựng để gọi nó.

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

thay vì hàm 'init', có chút xấu xí và dẫn người mới đến việc xây dựng giai đoạn hai giai đoạn, xem xét một đối tượng phụ: hoặc là thành viên dữ liệu hoặc lớp cơ sở (không quan trọng) –

+0

@Alf: Nếu init() là riêng tư, giải pháp đó không phải là xấu cả. – aggsol

0

Bạn nên thực hiện phương thức init() và gọi nó ở cả hai nhà thầu của bạn.

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

tạo ra một đối tượng tạm bóng và phá hủy nó ngay lập tức

1

Các câu trả lời khác cung cấp cách thực hiện cú pháp chính xác.

tôi sẽ làm một cái gì đó ngữ nghĩa chính xác để bạn gọi nó là như vậy:

Ball ball = Ball::createRandom(); 

Bạn thực hiện createRandom như một hàm static của Ball:

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

thực hiện như sau:

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

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

+1 Vì không cố gắng xoa bóp mã một cách mù quáng mà là suy nghĩ về những gì người dùng cần. –

+0

Cảm ơn. Tôi thử. Nó không phải lúc nào cũng đúng cách để trả lời các câu hỏi, và không phải lúc nào cũng nhận được upvotes, nhưng tôi không cố gắng để là câu trả lời duy nhất tốt nhất. Tôi muốn mở rộng ngữ cảnh. –

Các vấn đề liên quan