Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 构造函数中未定义的引用_C++_Undefined Reference - Fatal编程技术网

C++ 构造函数中未定义的引用

C++ 构造函数中未定义的引用,c++,undefined-reference,C++,Undefined Reference,在过去的两天里,我一直在努力解决这个问题,我已经在互联网上尝试过了每一种解决方案,现在开始 我对未定义的引用有问题。我正在做一个项目来比较3种算法,我把它们划分成3组不同的cpp文件。我使用的是DEC C++,GCC 4.92.6作为编译器。我知道这是一个链接器错误,但我所有的解决方案都不起作用,我似乎无法识别它 我的主要文件是 #include <iostream> #include <stdio.h> #include <string> #include

在过去的两天里,我一直在努力解决这个问题,我已经在互联网上尝试过了每一种解决方案,现在开始

我对未定义的引用有问题。我正在做一个项目来比较3种算法,我把它们划分成3组不同的cpp文件。我使用的是DEC C++,GCC 4.92.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);  
}
由于3个不同cpp文件的实现几乎相同,主要区别在于实现的算法以及一些杂项。已经编译的函数到目前为止没有显示错误,我将只显示Bresenham.cpp和hpp的主要部分,其中链接器错误正在发生。如果需要其他信息,请告诉我。对于下面显示的代码,GuptaSproull.cpp和XiaolinWu.cpp的定义几乎相同。为了便于阅读,我删掉了大部分函数实现,我认为这一部分没有关系,除非我弄错了。 布雷森汉姆水电站

#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
布雷森汉姆

    #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文件中。但是,上述错误仍然存在

这是否与我实现代码进行测试的方式有关?我使用了一个构造器来基本上运行我对算法的测试,我怀疑你可能会找到一种实现这种测试的劣质方法。我做了以下工作,所以是的,这些都不起作用:

已验证所有文件都位于同一项目下的生成路径中 尝试添加名称空间以查看是否修复了问题,但没有 为了找到一个可能的解决方案,我几乎搜索了谷歌的每一个链接,它们似乎都不起作用。 到目前为止,所有文件中都没有编译器错误。 我怀疑我可能需要放弃这种实现测试的方式,转而使用静态函数。有人能评论一下这是否可行吗?。我不太习惯C++,这是我目前为止的第一个大程序,所以请原谅我错过了一个非常明显的东西,我希望我没有。 我该怎么办

我该怎么办

首先,您需要设置正确的代码单元:

删除undef main没有意义 从cpp文件中删除,它们只属于头文件。有了这些,代码就不会被编译,因此出现了链接问题! 正如CodeFuller在回答中明确指出的那样,您必须将.hpp文件中的类声明与.cpp文件中方法的实现分开 更重要的是,你需要给我们一个证明你的问题的例子,我同意,这是一些工作

我该怎么办

首先,您需要设置正确的代码单元:

删除undef main没有意义 从cpp文件中删除,它们只属于头文件。有了这些,代码就不会被编译,因此出现了链接问题! 正如CodeFuller在回答中明确指出的那样,您必须将.hpp文件中的类声明与.cpp文件中方法的实现分开
关于更多内容,您需要给我们一个演示您的问题的示例,我同意,这是一项工作。

您实际上有两个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*/
}

实际上有两个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*/
}

如果你将include添加到Bresenham.hpp的标题会发生什么?我尝试了什么都没有发生我不认为这是问题如果你将include添加到Bresenham.hpp的标题会发生什么?我尝试了什么都没有发生我不认为这是问题不确定为什么会被否决,我认为那些在.cpp文件中包括警卫的人是问题的原因。我删除了我的否决票,然而,你的建议并不能解决作者的问题。好的,给我5分钟,我会看看我是否能编造一些东西来证明我的问题。而且,当我在做MVCE时,我会很快地说,头部防护装置和undef main是用来抑制我与其他错误有关的问题的。即使在没有这些行的情况下也会发生链接器错误。明白了,但是用一些奇怪的模式修复错误不是正确的方法…不确定为什么会被否决,我认为.cpp文件中包含的防护是问题的原因。我删除了我的否决票,然而,你的建议并不能解决作者的问题。好的,给我5分钟,我会看看我是否能编造一些东西来证明我的问题。而且,当我在做MVCE时,我会很快地说,头部防护装置和undef main是用来抑制我与其他错误有关的问题的。即使没有这些行,链接器错误也会发生。明白了,但是用一些奇怪的模式修复错误不是正确的方法。
同意我没有发现,但完全正确+1当我按照您的要求执行操作时,它会给我一个额外的限定条件“Bresenham::”在成员“Bresenham”[-fppermissive]上,您的cpp中可能仍然有类似于类Bresenham{Bresenham::Bresenhamsd::string…}的代码。你应该删除“Bresenham类”,让它像我发布的一样。给我一点时间让我试试,谢谢!取消布雷森汉姆的课程似乎是个好办法?此链接器错误的确切原因是什么?我想知道,这样我就不会再犯同样的错误了。同意!我没有发现,但完全正确+1当我按照您的要求执行操作时,它会给我一个额外的限定条件“Bresenham::”在成员“Bresenham”[-fppermissive]上,您的cpp中可能仍然有类似于类Bresenham{Bresenham::Bresenhamsd::string…}的代码。你应该删除“Bresenham类”,让它像我发布的一样。给我一点时间让我试试,谢谢!取消布雷森汉姆的课程似乎是个好办法?此链接器错误的确切原因是什么?我想知道,这样我就不会再犯同样的错误了。