2009-10-23 26 views
6

Tôi có một vấn đề trong MSVC++ 2008 nơi VS2008 được ném biên dịch lỗi này:C++ - "chức năng thành viên không tuyên bố" trong nguồn gốc lớp

error C2509: 'render' : member function not declared in 'PlayerSpriteKasua' 

Bây giờ, những gì khó hiểu tôi là render() được định nghĩa, nhưng trong một lớp kế thừa.

Định nghĩa lớp làm việc như thế này:

SpriteBase -Inherited By-> PlayerSpriteBase -Inherited By-> PlayerSpriteKasua 

Vì vậy, một phiên bản pared xuống của SpriteBase.h như sau:

class SpriteBase { 
public: 
    //Variables============================================= 
    -snip- 
    //Primary Functions===================================== 
    virtual void think()=0;       //Called every frame to allow the sprite to process events and react to the player. 
    virtual void render(long long ScreenX, long long ScreenY)=0; //Called every frame to render the sprite. 
    //Various overridable and not service/event functions=== 
    virtual void died();       //Called when the sprite is killed either externally or via SpriteBase::kill(). 
    -snip- 
    //====================================================== 
}; 

PlayerSpriteBase.h là thế này:

class PlayerSpriteBase : public SpriteBase 
{ 
public: 
    virtual void pose() = 0; 
    virtual void knockback(bool Direction) = 0; 
    virtual int getHealth() = 0; 
}; 

Và cuối cùng, PlayerSpriteKasua.h là:

class PlayerSpriteKasua : public PlayerSpriteBase 
{ 
public: 
}; 

Tôi biết chưa có thành viên nào trong đó, nhưng đó đơn giản là vì tôi chưa thêm chúng. Cũng vậy với PlayerSpriteBase; còn nhiều thứ khác để đi vào đó.

Các mã trong PlayerSpriteKasua.cpp là thế này:

#include "../../../MegaJul.h" //Include all the files needed in one go 

void PlayerSpriteKasua::render(long long ScreenX, long long ScreenY) { 
    return; 
} 
void PlayerSpriteKasua::think() { 
    return; 
} 
int PlayerSpriteKasua::getHealth() { 
    return this->Health; 
} 

Khi tôi gõ, nói, void PlayerSpriteKasua::, Intellisense bật lên danh sách tất cả các thành viên của PlayerSpriteBase và SpriteBase tốt, nhưng trên biên dịch nó không thành công như tôi đã nói ở trên.

Có lý do cụ thể nào khiến tôi gặp phải lỗi này không?

PlayerSpriteBase.cpp trống và chưa có gì trong đó.

SpriteBase.cpp có rất nhiều định nghĩa chức năng cho SpriteBase, và sử dụng định dạng giống như PlayerSpriteKasua.cpp:

void SpriteBase::died() { 
    return; 
} 

là một ví dụ.

Trả lời

16

Trong PlayerSpriteKasua.h bạn cần phải khai báo lại bất kỳ phương thức nào bạn sẽ ghi đè/triển khai (không có "= 0" để nói rằng các phương thức đó không trừu tượng nữa). Vì vậy, bạn cần phải viết nó như sau:

class PlayerSpriteKasua : public PlayerSpriteBase 
{ 
public: 
    virtual void think(); 
    virtual void render(long long ScreenX, long long ScreenY); 
    virtual int getHealth(); 
}; 

... hoặc bạn đã bỏ sót điều đó để giữ cho bài viết của bạn ngắn hơn?

+0

Đây là sự cố ngay tại đây. Tôi không biết rằng về C++ đã tự dạy nó. Cảm ơn! – Sukasa

+5

Tốt! Lưu ý rằng bạn không thực sự phải chỉ định "ảo" một lần nữa ở đây (nó sẽ hoạt động tốt mà không có nó), nhưng thực hành tốt là để nó, vì nó cho ai biết mã của bạn rằng các phương thức này được thừa hưởng từ một trong các lớp cơ sở . – Ludovic

+2

Tôi đến từ nền C# và điều này thật điên rồ. Nó phá vỡ DRY, đặc biệt là nếu bạn có nhiều chiến lược làm điều tương tự. –

2

Bạn cần cung cấp tuyên bố cho PlayerSpriteKasua :: render() trong định nghĩa lớp học của bạn. Nếu không, các đơn vị dịch thuật khác bao gồm PlayerSpriteKasua.h của bạn sẽ không thể nói rằng bạn đã cung cấp một định nghĩa và sẽ buộc phải kết luận rằng PlayerSpriteKasua không thể được khởi tạo.

2

Bạn cần phải redeclare các thành viên của SpriteBase rằng bạn sẽ thực hiện trong PlayerSpriteKasua trong tuyên bố của PlayerSpriteKasua trong PlayerSpriteKasua.h.

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