2016-03-03 75 views
-1

過去兩天我一直在琢磨這件事,而且我已經嘗試了互聯網上的每一種解決方案,所以在這裏。未定義在構造函數中的引用

我有未定義的引用問題。我正在做一個項目來比較3種算法,我將它們劃分爲3組不同的cpp文件。我使用Dev C++和gcc 4.9.2.6作爲我的編譯器。我知道這是一個鏈接器錯誤,但是我的所有解決方案都無法正常工作,我似乎無法識別它。

我的主要文件是

#include <iostream> 
#include <stdio.h> 
#include <string> 
#include <fstream> 
#include <time.h> 
#include "SDL.h" 

#include "bitmap_image.hpp" //ext 
#include "Bresenham.hpp" 
#include "XiaolinWu.hpp" 
#include "GuptaSproull.hpp" 

void GenerateBMPBlank(int xsize,int ysize,std::string fileid); 
void BresenhamTest(int xsize,int ysize, std::string TestDataFile); 
void XiaolinWuTest(int xsize,int ysize, std::string TestDataFile); 
void GuptaSproullTest(int xsize, int ysize, std::string TestDataFile); 
void executeTest(int xsize,int ysize, std::string TestDataFile); //resulting BMP file generated will have the format "x_y_algorithmName.bmp" 

int main() 
{ 
    short x,y; 
    std::string TestFileLocation; 
    std::cout << "Please indicate file path of Test Data textfile"<< std::endl; 
    std::cin>>TestFileLocation; 
    std::cout << "Please indicate file dimensions" << std::endl; 
    std::cin>> x >> y; 
    executeTest(x,y, TestFileLocation); 
    std::cout<< "Procedure executed"<< std::endl; 
    std::cin.get(); 
    return 0; 
} 

void GenerateBMPBlank(int xsize,int ysize,std::string fileid) //uses external library http://partow.net/programming/bitmap/ to generate a blank white bmp file 
{ 
    bitmap_image blankBMP(xsize,ysize); //creates bitmap image 
    blankBMP.set_all_channels(255,255,255); //sets entire image to be completely white 
    blankBMP.save_image(fileid); 
} //tested 

void executeTest(int xsize,int ysize, std::string TestDataFile) 
{ 
    SDL_Init(SDL_INIT_EVERYTHING); 
    std::cout<<"Beginning test of data set from "+TestDataFile<<std::endl; 
    std::cout<<"Now executing Bresenham's algorithm"<<std::endl; 
    BresenhamTest(xsize,ysize, TestDataFile); 
    std::cout<<"Now executing Xiaolin Wu's algorithm"<<std::endl; 
    XiaolinWuTest(xsize,ysize,TestDataFile); 
    std::cout<<"Now executing Gupta Sproull 's algorithm"<<std::endl; 
    GuptaSproullTest(xsize,ysize,TestDataFile); 
    SDL_Quit(); 
} 

void BresenhamTest(int xsize,int ysize, std::string TestDataFile) 
{ 
    std::string ResultName= std::to_string(xsize) + "_" + std::to_string(ysize) + "_Bresenham.bmp"; 
    GenerateBMPBlank(xsize,ysize,ResultName); 
    clock_t tStart = clock(); 
    Bresenham b(ResultName,TestDataFile); 
    printf("Time taken for Bresenham: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC); 
} 
void XiaolinWuTest(int xsize,int ysize, std::string TestDataFile) 
{ 
    std::string ResultName= std::to_string(xsize) + "_" + std::to_string(ysize) + "_XiaolinWu.bmp"; 
    GenerateBMPBlank(xsize,ysize,ResultName); 
    clock_t tStart = clock(); 
    XiaolinWu w(ResultName,TestDataFile); 
    printf("Time taken for XiaolinWu: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC); 
} 
void GuptaSproullTest(int xsize,int ysize, std::string TestDataFile) 
{ 
    std::string ResultName= std::to_string(xsize) + "_" + std::to_string(ysize) + "_GuptaSproull.bmp"; 
    GenerateBMPBlank(xsize,ysize,ResultName); 
    clock_t tStart = clock(); 
    GuptaSproull g(ResultName,TestDataFile); 
    printf("Time taken for GuptaSproull: %.4fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC); 
} 

然而,一個錯誤被如下

C++ files/ComparatorMain.o:ComparatorMain.cpp:(.text+0x544): undefined reference to `Bresenham::Bresenham(std::string, std::string)' 
C++ files/ComparatorMain.o:ComparatorMain.cpp:(.text+0x76b): undefined reference to `XiaolinWu::XiaolinWu(std::string, std::string)' 
C++ files/ComparatorMain.o:ComparatorMain.cpp:(.text+0x992): undefined reference to `GuptaSproull::GuptaSproull(std::string, std::string)'collect2.exe: error: ld returned 1 exit status 

作爲3個不同的cpp文件的實現方式產生的幾乎是相同的(與主要區別只是作爲算法實現以及一些符合目前沒有顯示錯誤的雜項函數),我將只顯示Bresenham.cpp和hpp中鏈接器錯誤發生的主要部分(如果需要其他信息,請告訴我)。 GuptaSproull.cpp和XiaolinWu.cpp的定義與下面顯示的代碼非常相似。爲了便於閱讀,我剪掉了大部分的函數實現,我不認爲它是相關的(除非我弄錯那部分)。 Bresenham.hpp

#ifndef BRESENHAM_H 
#define BRESENHAM_H 

#include <iostream> 
#include "SDL.h" 
#undef main 


class Bresenham{ 


    public: 
     Bresenham(std::string BMPName,std::string TestDataFile); 
     SDL_Surface* OpenBMP(std::string BMPName); 
     void CloseBMP(SDL_Surface* surface,std::string Filename); 
     void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel); 
     void bresenhamDrawLine(int x1,int y1,int x2, int y2, SDL_Surface *surface); 

}; 

#endif 

Bresenham.cpp

#ifndef BRESENHAM_H 
    #define BRESENHAM_H 

    #include <iostream> 
    #include <cstdio> 
    #include <cmath> 
    #include <fstream> 
    #include "SDL.h" 
    #include "Bresenham.hpp" 
    #undef main 

    #endif 
    class Bresenham 
    { 
     Bresenham(std::string BMPName,std::string TestDataFile) 
     { 
      std::ifstream testFile(TestDataFile); 
      SDL_Surface *image; 
      image=OpenBMP(BMPName); 
      if (SDL_MUSTLOCK(image)) //surface must be locked before pixels can be drawn 
      { 
       if (SDL_LockSurface(image) < 0) { 
        fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 
        return; 
       } 
      } 
      int x1,y1,x2,y2; 
      while(testFile>>x1>>y1>>x2>>y2) 
      { 
       bresenhamDrawLine(x1,y1,x2,y2,image); //loops through the dataset and calls the bresenham draw line function 
      } 
      if (SDL_MUSTLOCK(image)) 
      { 
       SDL_UnlockSurface(image); 
      } 
      CloseBMP(image,BMPName); 
     } 

     void bresenhamDrawLine(int x1,int y1,int x2, int y2, SDL_Surface *surface) 
     { 
/* implemented */ 
     } 
     SDL_Surface* OpenBMP(std::string BMPName) 
     { 
      /* implemented */ 
     } 

     void CloseBMP(SDL_Surface *surface,std::string FileName) 
     { 
      /* implemented */ 
     } 

     void putpixel(SDL_Surface *surface, int x, int y, double brightness) //this function allows us to place a pixel at coordinates (x,y) in SDL. 
     { 
      /*implemented*/ 
     } 

    }; 

現在我已經做了一些嘗試凌亂,試圖解決這個問題(如添加#ifndef BRESENHAM_H #define BRESENHAM_H #include "Bresenham.hpp"到.cpp文件。但是,錯誤以上問題仍然存在

這是否與我執行測試代碼的方式有關?我使用了一個構造函數來基本上對算法進行測試(我懷疑你可能會發現一種僞劣的方法來執行這樣的測試)。 我已經做好了下面的(所以是那些沒有工作):

  1. 確認所有文件都在構建路徑(在同一項目中)
  2. 嘗試添加命名空間,看它是否解決了這一問題(它沒't)
  3. 我已經搜索了幾乎在谷歌每一個鏈接,以找到一個潛在的修復(他們都沒有似乎工作)。
  4. 到目前爲止,沒有編譯器錯誤(在所有文件中)。

我懷疑我可能需要放棄這種風格的實現測試,並遷移到使用靜態函數(可以有人評論,如果這將工作?)。我並不是很習慣C++(這是我迄今爲止第一個使用這種語言的「大」程序),所以如果我錯過了一些顯而易見的東西(我希望我沒有),請原諒我。

我該怎麼辦?

+0

如果添加的#include''向Bresenham.hpp的頭會發生什麼? – Xirema

+0

我什麼都沒有發生,我不認爲它的問題 –

回答

4

實際上你有兩個Bresenham類的聲明,一個在Bresenham.hpp中,另一個在Bresenham.cpp中。更改下列方式您的CPP文件:

Bresenham::Bresenham(std::string BMPName,std::string TestDataFile) 
{ 
    std::ifstream testFile(TestDataFile); 
    SDL_Surface *image; 
    image=OpenBMP(BMPName); 
    if (SDL_MUSTLOCK(image)) //surface must be locked before pixels can be drawn 
    { 
     if (SDL_LockSurface(image) < 0) { 
      fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); 
      return; 
     } 
    } 
    int x1,y1,x2,y2; 
    while(testFile>>x1>>y1>>x2>>y2) 
    { 
     bresenhamDrawLine(x1,y1,x2,y2,image); //loops through the dataset and calls the bresenham draw line function 
    } 
    if (SDL_MUSTLOCK(image)) 
    { 
     SDL_UnlockSurface(image); 
    } 
    CloseBMP(image,BMPName); 
} 

void Bresenham::bresenhamDrawLine(int x1,int y1,int x2, int y2, SDL_Surface *surface) 
{ 
/* implemented */ 
} 
SDL_Surface* Bresenham::OpenBMP(std::string BMPName) 
{ 
    /* implemented */ 
} 

void Bresenham::CloseBMP(SDL_Surface *surface,std::string FileName) 
{ 
    /* implemented */ 
} 

void Bresenham::putpixel(SDL_Surface *surface, int x, int y, double brightness) //this function allows us to place a pixel at coordinates (x,y) in SDL. 
{ 
    /*implemented*/ 
} 
+0

同意!我沒有發現,但完全正確! +1 – kebs

+0

當我做你告訴我的,它給了我一個「額外資格」Bresenham ::'在成員'Bresenham'[-fmissmissive] –

+1

你可能仍然有類Bresenham {Bresenham :: Bresenham(std :: string ...)}在你的cpp中,你應該刪除'class Bresenham'並且像我發佈的一樣離開它 – CodeFuller

2

我該怎麼辦?

首先,您需要設置正確的代碼單元:

  • 刪除#undef main(沒有意義)
  • 刪除您cpp文件的include guards,他們只在頭文件屬於。有了這些,代碼就不會被編譯,因此鏈接問題!
  • 作爲CodeFuller明確指出在他的答案,你必須分開類的聲明(在.HPP文件)和方法的實現(在.cpp文件)

更多,你需要給我們MVCE,這表明你的問題(我同意,這是一些工作)。

+0

不知道爲什麼這是得到downvoted,我認爲這些包括在.cpp文件中的警衛是問題的原因。 – Xirema

+0

我刪除了我的downvote,但是您的提議並未解決作者的問題。 – CodeFuller

+0

好吧,給我5分鐘,我會看看我是否可以做出一些能夠證明我的問題的東西 –