2012-08-12 36 views
5

Tôi đang viết một trò chơi đơn giản trong SDL. Tôi có một chế độ thừa kế lớp mà tôi đang xây dựng cho bất kỳ sprite nào tôi sử dụng trong game. Lớp cơ sở là Sprite, chứa các trừu tượng dữ liệu cho hộp va chạm và spritesheet. Trực tiếp dưới đây là hai lớp trừu tượng, Ký tự và MapObject.Lớp cơ sở không thể tiếp cận

Tôi hiện đang triển khai lớp Trình phát bắt nguồn từ Ký tự (Kẻ thù và NPC cũng sẽ được bắt nguồn từ lớp Ký tự trừu tượng).

Dù sao, hy vọng điều đó có ý nghĩa. Vấn đề của tôi là:

Khi tôi thử và sử dụng lớp trình phát trong công cụ, tôi không thể truy cập bất kỳ chức năng nào của Sprite.

tôi nhận được lỗi sau:

'Sprite' is not an accessible base of 'Player' 

Dưới đây là các tập tin tiêu đề:

Sprite.h:

class Sprite{ 
public: 
    virtual ~Sprite() = 0; //I want this to be an abstract class and yes this is defined in the cpp 

    //Initialization functions - MUST be called before anything else in the class can be used. 
    void setupCollider(int xo, int yo, int ho, int wo); 
    void setupSheet(SDL_Surface* dest, std::string file, int numClips, int ac, int _res, int sr); 

    //SpriteSheet functions 
    void setActiveClip(int a); 
    int getActiveClip() const; 
    void draw() const; 
    int getResolution() const; 
    SDL_Surface* getDest(); 


    //Collider functions 
    void updateCollider(); 
    SDL_Rect box() const; 
    bool collision(SDL_Rect other) const; 

    //Access and Modify coordinates of the sprite 
    void setLoc(int x, int y) { _x = x; _y = y; } 
    int getX() const { return _x; } 
    int getY() const { return _y; } 

private: 
    struct Collider{ 
     SDL_Rect _box; 
     int  x_offset, 
        y_offset; 
    }; 

    struct SpriteSheet{ 
     SDL_Surface*  destination; 
     SDL_Surface* sheet; 
     SDL_Rect*  clips; 
     int    _numClips; 
     int    active; 
     int    res; 
     int    sheetrows; 
    }; 


    Collider  collisionAttributes; 
    SpriteSheet spriteSheetAttributes; 
    int   _x, _y; 

}; 

Character.h:

class Character : public Sprite{ 
public: 
    virtual void move(Direction direction_input, const TileMap& currentlevel) = 0; 
    virtual void animate() = 0; 

    virtual void setAttributes(int h, int sp, int ad, int d, int m, int md, int l, std::string n){ 
     hearts = h; speed = sp; attackdamage = ad; 
     defense = d; magicdamage = m; magicdefense = md; 
     level = l; name = n; 
    } 

    bool isDead() const{ 
     return hearts == 0; 
    } 

    void heal(int heartsup){ 
     hearts += heartsup; 
    } 

    void dealDamage(int heartsDown){ 
     hearts -= heartsDown; 
    } 


protected: 

    int hearts; 
    int speed; 
    int attackdamage; 
    int defense; 
    int magicdamage; 
    int magicdefense; 
    int level; 
    std::string name; 

}; 

chơi .h:

//Not fully finished yet, but should work for the purposes of this question 
class Player : protected Character{ 
public: 
    ~Player(){ 
     if(heart) SDL_FreeSurface(heart); 
    } 
    static const int HEART_WIDTH; 

    void move(Direction direction_input, const TileMap& currentlevel); 
    void animate(); 

    void updateCamera(TileMap& currLevel); 


private: 

    SDL_Surface* heart; 

    enum ClipFace 
    { 
     UP1, 
     UP2, 
     DOWN1, 
     DOWN2, 
     LEFT1, 
     LEFT2, 
     RIGHT1, 
     RIGHT2 
    }; 

    static const std::string HEART; 
    static const int HEART_RES; 

}; 

tôi nhận được lỗi đầu tiên trong động cơ của tôi khi tôi cố gắng để gọi các chức năng cài đặt từ Sprite trong máy nghe nhạc, một trong những con người đầu tiên:

player.setLoc(levels[0].startX(), levels[0].startY()); 

Bất kỳ và tất cả help is appreciated.

[SOLVED] EDIT: Một giải pháp thay thế cho các nhận xét: Lớp nhân vật không kế thừa bất kỳ thứ gì từ lớp Sprite, vì vậy nó không phải bắt nguồn từ nó. Thay vì có ký tự kế thừa từ Sprite, tôi có Player kế thừa từ BOTH Sprite và Character và nó cũng hoạt động. Tôi không chắc thiết kế nào tốt hơn.

+1

Bạn đã hạn chế quyền truy cập một cách rõ ràng và bạn có thể truy cập nó một cách rõ ràng không? –

+1

Bạn có thể muốn xem xét làm cho 'Sprite' thành viên (có thể tùy chọn/nullable) của' Character', thay vì sử dụng các mối quan hệ thừa kế ở đó. – aschepler

Trả lời

10

Tôi nghĩ rằng bạn cần phải thay đổi

class Player : protected Character{ 

để

class Player : public Character{ 

Bằng cách đó bạn có thể truy cập CharacterSprite 's chức năng trên một đối tượng Player từ một thể hiện của Player tạo bất cứ nơi nào trong chương trình của bạn .

Nếu Player có thể làm bất cứ điều gì một Character có thể làm, public kế thừa có ý nghĩa. Không có lý do gì để ẩn nội dung nào đó trong Player mà có thể truy cập miễn phí trong các đối tượng Character hoặc Sprite.

+0

Tôi nghĩ rằng làm cho nó được bảo vệ cho nó truy cập nhiều hơn. Vì vậy, bây giờ thay vì chỉ có công chúng nó đã được công khai và bảo vệ. Có vẻ như sự hiểu biết của tôi đang thiếu ở đây. Bạn có thể xây dựng thêm? – Slims

+1

@Slims Không, không hoàn toàn! Câu trả lời này có một giải thích tuyệt vời về tư nhân/bảo vệ/công cộng: http://stackoverflow.com/a/860353/1023783 Hãy cho tôi biết nếu bạn vẫn còn bối rối sau khi đọc nó và tôi sẽ cố gắng để xây dựng! – WendiKidd

+0

Cảm ơn rất nhiều, đã xóa nó cho tôi! – Slims

0

Tôi muốn đặt cược rằng vì Character là lớp cơ sở được bảo vệ, nên hạn chế quyền truy cập vào Sprite.

1

Luôn sử dụng public kế thừa để đại diện cho mối quan hệ "là-a". Có vẻ như Player là một Character, vì vậy thừa kế phải là public, không phải protected.

protected kế thừa và private thừa kế giống như "has-a" (và trong hầu hết các trường hợp, thành viên con là cách dễ dàng hơn để đối phó với mối quan hệ đó).

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