2013-01-22 93 views
0

現在我已經將多態性與單個子類合併在一起。其中兩個函數,如下面的代碼所示,Draw()和SetValue(int,int,int)導致鏈接器錯誤。C++頭文件需要對另一個類的函數的引用

#include "Header.h" 

class Object{ 
int tag; 
public: 
void SetValues(int,int,int); 
void Draw(); 
int getTag(){ 
    return tag; 
} 
}; 
class Square: public Object{ 
int red; 
int green; 
int blue; 
void Draw(); 
void SetValues(int red2,int green2, int blue2){ 
red=red2; 
green=green2; 
blue=blue2; 
} 
}; 
void Square::Draw(){ 
// Draws a square with a gradient color at coordinates 0, 10 
    glBegin(GL_QUADS); 
    { 
glColor3f(red, green, blue); 
glVertex2i(1, 11); 
glColor3f(red * .8, green * .8, blue * .8); 
glVertex2i(-1, 11); 
glColor3f(red * .5, green * .5, blue * .5); 
glVertex2i(-1, 9); 
glColor3f(red * .8, green * .8, blue * .8); 
glVertex2i(1, 9); 
    } 
    glEnd(); 
} 

的錯誤

Error 1 error LNK2019: unresolved external symbol "public: void __cdecl Object::SetValues(int,int,int)" ([email protected]@@[email protected]) referenced in function "public: void __cdecl State::DrawAll(void)" ([email protected]@@QEAAXXZ) C:\Users\Asher\documents\visual studio 2012\Projects\Procedural Terrain\Procedural Terrain\State.obj Procedural Terrain 
Error 2 error LNK2019: unresolved external symbol "public: void __cdecl Object::Draw(void)" ([email protected]@@QEAAXXZ) referenced in function "public: void __cdecl State::DrawAll(void)" ([email protected]@@QEAAXXZ) C:\Users\Asher\documents\visual studio 2012\Projects\Procedural Terrain\Procedural Terrain\State.obj Procedural Terrain 

在更大的類,它確實沒有繼承對象的功能,使用DrawAll(),在它的draw()調用。 cpp文件和兩個相應的頭文件如下。

#include "Header.h" 
#include "Object.h" 
float rotate_z=0; 
class State{ 
private: 
std::vector<Object> storage; 
public: 
State(); 
State Interpolate(State, State, double); 
void Integrate(State,double, const double); 
void DrawAll(); 
void AddObject(Object); 
void RemoveObject(int); 
}; 
State::State(){ 

} 
State State::Interpolate(State current,State previous,const double alpha){ 
//current*alpha + previous * (1.0 - alpha); 
return current; 
} 
void State::Integrate(State current, double t, const double dt){ 
} 
void State::AddObject(Object object){ 
storage.push_back(object); 
} 
void State::RemoveObject(int tag){ 
//for(int i=0;i<storage.size;i++){ 
// if(storage.at(i).getTag==tag){ 
//storage.erase(storage.begin()+i); 
// } 
//} 
} 
void State::DrawAll(void) 
{ 
    // reset view matrix 
    glLoadIdentity(); 
// move view back a bit 
glTranslatef(0, 0, -30); 
// apply the current rotation 

glRotatef(rotate_z, 0, 0, 1); 
rotate_z += 5; 
// by repeatedly rotating the view matrix during drawing, the 
// squares end up in a circle 
int i = 0, squares = 15; 
float red = 0, blue = 1; 
for (; i < squares; ++i){ 
    Square square; 
Object * squareP=&square; 
glRotatef(360.0/squares, 0, 0, 1); 
// colors change for each square 
red += 1.0/12; 
blue -= 1.0/12; 
squareP->SetValues(red,0.6,blue); 
squareP->Draw(); 
    } 
} 

對象頭 -

#ifndef Object_H 
#define Object_H 

class Object{ 
int tag; 

public: 
void SetValues(int,int,int); 
void Draw(); 
int getTag(); 
}; 
class Square: public Object{ 
int red; 
int green; 
int blue; 
void Draw(); 
void SetValues(int red2,int green2, int blue2); 
}; 
#endif 

最後的State頭 -

#ifndef State_H 
#define State_H 

#include "Object.h" 
#include <vector> 
class State{ 
private: 
std::vector<Object> storage; 
public: 
State(); 
State Interpolate(State, State, double); 
void Integrate(State,double, const double); 
void DrawAll(); 
void AddObject(Object); 
void RemoveObject(int); 
}; 
#endif 

這是第一個C++項目我已經在工作,並沒有從Java背景完全轉移。問題是什麼?

回答

1

Object類有 「抽象」 的方法(如Java)沒有執行SetValues功能。您可能需要一個純虛函數。相同的Draw

class Object { 
    virtual void SetValues(int,int,int) = 0; 
} 

另請注意,在C++中,函數默認情況下不是虛擬的。您必須在基類中明確使用virtual關鍵字。

另外class Object似乎被定義在多個地方。爲什麼?在Object.h中定義它就足夠了。

請縮進您的代碼,因爲它很難閱讀。

另外std::vector<Object>不會做你想做的!在Java中,所有東西都是引用,在C++中,事物按值存儲在std::vector中,因此您的代碼受制於切片問題。你想在那裏使用一個指針(std::vector<Object*>),但是智能指針會更好(std::vector<std::shared_ptr<Object>>

+0

在執行上述操作時(除了類Object的多重聲明,因爲我看不到多個),我得到一個錯誤:錯誤錯誤LNK2001:無法解析的外部符號「private:virtual void __cdecl Square :: SetValues(int,int, int)「(?SetValues @ Square @@ EEAAXHHH @ Z)\t C:\ Users \ Asher \ documents \ visual studio 2012 \ Projects \ Procedural Terrain \ Procedural Terrain \ State.obj \t Procedural Terrain' – Behemyth

+0

沒關係,我忘了移動SetValues,現在一切都很好,很好看!我非常感謝幫助! – Behemyth

1

什麼都沒有標記爲virtual,我看不到Object :: Draw()或Object :: SetValues()的任何實現。

在C++中允許子類覆蓋基類中的函數,它需要被標記爲virtual(在Java中,所有東西都是「虛擬的」)。

您可以通過說出

class Object { 
    public: 
     virtual void SetValues(int,int,int) = 0; 
+0

當我將這些函數改爲抽象函數時,我得到錯誤說我不能直接引用那個抽象類。但是,我需要能夠將Square和其他多個實體存儲在具有相同基本功能的向量中。通過不直接引用對象,我不知道該怎麼做。 – Behemyth

+0

通過遵循你的幫助和Csq的幫助,我能夠找出虛擬關鍵字並使用指針來引用類。非常感謝你! – Behemyth

相關問題