c ++中的多个定义错误

时间:2011-10-02 13:57:07

标签: c++ graphics

这是我在DevCpp(windows)中编写的一些代码,现在我试图让它在Linux中运行而没有太大的成功。 这是源代码

screen.h

#ifndef SCREEN_H
#define SCREEN_H

#include <graphics.h>

class Screen
{
      private:
              int max_x,max_y,grid_size;
              int delta_x,delta_y;
              int origin_x,origin_y;
      public:
      // Default Constructor to Initialize the screen with the grid
      Screen(int xcoord=641, int ycoord=641, int grid=8)
      {
           //variable initialization
           max_x = xcoord;
           max_y = ycoord;
           grid_size = grid;

           delta_x = max_x / grid_size;
           delta_y = max_y / grid_size;

           origin_x = grid_size / 2 * delta_x;
           origin_y = grid_size / 2 * delta_y;

           //plotting the initial grid
           int gd,gm;
           initgraph(&gd,&gm,NULL);
            //draw the x component of the grid
             for(int i=0; i<max_x; i += delta_x)
             {
                     if( i != max_x / 2)
                         setcolor(GREEN);
                     else
                         setcolor(RED);
                    line(i,0,i,max_y);
             }
             //draw the y component of the grid
             for(int i=0; i<max_y; i += delta_y)
             {
                     if( i != max_y / 2)
                         setcolor(GREEN);
                     else
                         setcolor(RED);
                     line(0,i,max_x,i);
             }
             //mark the origin with a white dot to acertain its coordinates for future use
             putpixel(origin_x,origin_y,WHITE);
             std::cout<<origin_x<<"\t"<<origin_y<<"\n";
        }



      //Method prototypes
      void plot_pixel(int xcoord,int ycoord,int col=WHITE)
      {
        int l,t,r,b;
        l = origin_x + xcoord * delta_x;
        r = l + delta_x;
        b = origin_y - ycoord * delta_y;
        t = b - delta_y;
        setcolor(col);
        bar(l,t,r,b);
        setcolor(WHITE);
     }
};
#endif

circles.cpp

#include<iostream>
#include<cmath>
#include "screen.h"
using namespace std;

void draw_midpoint_circle(Screen ob, int radius);
void circlepointplot(Screen ob, int m, int n);
void trigonometric_circle(Screen ob, int radius);

int main() {
    Screen scr = Screen(641, 641, 16);
    int choice, rad;
    cout << "Menu\n 1. Midpoint Circle Drawing Algorithm\n 2. Bresenham's Circle Drawing Algorithm \n 3. Trigonometric Method\n";
    cin>>choice;
    cout << "Enter Radius \t";
    cin>>rad;

    switch (choice) {
        case 1:
            draw_midpoint_circle(scr, rad);
            break;
        case 2:
            draw_midpoint_circle(scr, rad);
            break;
        case 3:
            trigonometric_circle(scr, rad);
            break;
        default:
            cout << "Wrong Choice\n";
            break;
    }

    getch();
    return 0;
}

void trigonometric_circle(Screen ob, int radius) {
    double angle = 0.0;
    while (angle <= 360) {
        int dx = 641 / 16;
        int x = int(radius * cos(angle));
        int y = int(radius * sin(angle));
        angle = angle + 5;
        ob.plot_pixel(x, y, 0);
        cout << "Point Plotted  " << x << "\t" << y << endl;
        char buffer[50];
        sprintf(buffer, "%d,%d", x, y);
        outtextxy(320 + ((x + 1) * dx), 320 - ((y - 1) * dx), buffer);
        getch();
    }
}

void draw_midpoint_circle(Screen ob, int radius) {
    float dp;
    int x, y;
    x = 0;
    y = radius;
    dp = 1 - radius;
    while (x < y) {
        circlepointplot(ob, x, y);
        if (dp < 0)
            dp = dp + 2 * x + 3;
        else {
            dp = dp + 2 * (x - y) + 5;
            y--;
        }

        x++;
        circlepointplot(ob, x, y);
    }
}

void circlepointplot(Screen ob, int m, int n) {
    ob.plot_pixel(m, n, 0);
    ob.plot_pixel(n, m, 0);
    ob.plot_pixel(m, -n, 0);
    ob.plot_pixel(n, -m, 0);
    ob.plot_pixel(-m, n, 0);
    ob.plot_pixel(-n, m, 0);
    ob.plot_pixel(-m, -n, 0);
    ob.plot_pixel(-n, -m, 0);

    cout << "Point Plotted" << m << "\t" << n << endl;
    cout << "Point Plotted" << n << "\t" << m << endl;
    cout << "Point Plotted" << m << "\t" << -n << endl;
    cout << "Point Plotted" << n << "\t" << -m << endl;
    cout << "Point Plotted" << -m << "\t" << n << endl;
    cout << "Point Plotted" << -n << "\t" << m << endl;
    cout << "Point Plotted" << -m << "\t" << -n << endl;
    cout << "Point Plotted" << -n << "\t" << -m << endl;
    int dx = 641 / 16;
    char buffer[50];
    sprintf(buffer, "%d,%d", m, n);
    outtextxy(320 + ((m + 1) * dx), 320 - ((n - 1) * dx), buffer);
    getch();

}

我正在使用graphics.h用于linux。基本程序运行正常。 我得到的错误是

g++ -c screen.cpp -o screen.o
g++ -c circles.cpp -o circles.o
g++ screen.o circles.o -o "circle.exe" -lgraph
circles.o:(.bss+0x0): multiple definition of `screen'
screen.o:(.bss+0x0): first defined here
circles.o:(.bss+0x8): multiple definition of `Font_surface'
screen.o:(.bss+0x8): first defined here
circles.o:(.bss+0x10): multiple definition of `_fgcolor'
screen.o:(.bss+0x10): first defined here
circles.o:(.bss+0x14): multiple definition of `_bgcolor'
screen.o:(.bss+0x14): first defined here
circles.o:(.bss+0x18): multiple definition of `_fontcolor'
screen.o:(.bss+0x18): first defined here
circles.o:(.bss+0x1c): multiple definition of `_pid'
screen.o:(.bss+0x1c): first defined here
circles.o:(.bss+0x20): multiple definition of `CP'
screen.o:(.bss+0x20): first defined here
circles.o:(.bss+0x40): multiple definition of `InternalFont'
screen.o:(.bss+0x40): first defined here
circles.o:(.bss+0x850): multiple definition of `TP'
screen.o:(.bss+0x850): first defined here
circles.o:(.bss+0x860): multiple definition of `_last_arc'
screen.o:(.bss+0x860): first defined here
circles.o:(.bss+0x878): multiple definition of `_internal_linestyle'
screen.o:(.bss+0x878): first defined here
circles.o:(.bss+0x888): multiple definition of `_scanlist'
screen.o:(.bss+0x888): first defined here
collect2: ld returned 1 exit status

我做错了什么,如何让它发挥作用?

将代码移入课程后更新了错误。

/tmp/ccB2RO2Q.o: In function `main':
circles.cpp:(.text+0x111): undefined reference to `grgetch'
/tmp/ccB2RO2Q.o: In function `trigonometric_circle(Screen, int)':
circles.cpp:(.text+0x242): undefined reference to `outtextxy'
circles.cpp:(.text+0x247): undefined reference to `grgetch'
/tmp/ccB2RO2Q.o: In function `circlepointplot(Screen, int, int)':
circles.cpp:(.text+0x6f2): undefined reference to `outtextxy'
circles.cpp:(.text+0x6f7): undefined reference to `grgetch'
/tmp/ccB2RO2Q.o: In function `Screen::Screen(int, int, int)':
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0xd0): undefined reference to `initgraph'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0xf7): undefined reference to `setcolor'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x103): undefined reference to `setcolor'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x11c): undefined reference to `line'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x15e): undefined reference to `setcolor'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x16a): undefined reference to `setcolor'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x182): undefined reference to `line'
circles.cpp:(.text._ZN6ScreenC2Eiii[_ZN6ScreenC5Eiii]+0x1b9): undefined reference to `putpixel'
/tmp/ccB2RO2Q.o: In function `Screen::plot_pixel(int, int, int)':
circles.cpp:(.text._ZN6Screen10plot_pixelEiii[Screen::plot_pixel(int, int, int)]+0x6d): undefined reference to `setcolor'
circles.cpp:(.text._ZN6Screen10plot_pixelEiii[Screen::plot_pixel(int, int, int)]+0x80): undefined reference to `bar'
circles.cpp:(.text._ZN6Screen10plot_pixelEiii[Screen::plot_pixel(int, int, int)]+0x8a): undefined reference to `setcolor'
collect2: ld returned 1 exit status

这是graphics.h文件,它引用了SDL_Image *屏幕

/* libgraph - TurboC graphics API on GNU/Linux
 * graphics.h: Core initialization and configuration functions
 * 
 * Copyright (C) 2003  Faraz Shahbazker
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 *  MA 02111-1307, USA
 *
 * Author:  Faraz Shahbazker <faraz_ms@rediffmail.com>
 */

/* Graphic functions using SDL */

#ifndef GRAPHICS_H
#define GRAPHICS_H 1


#include <SDL/SDL.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


#ifdef __cplusplus
extern "C" 
{

#endif      /* __cplusplus */


/* graphic drivers */
enum _driver{DETECT=0, USER, VGA=9};
enum graphics_modes{VGALO=0, VGAMED, VGAHI, VGAMAX, VGA640, VGA800, VGA1024, USERMODE};


/* 16 colors */
enum _color{BLACK=0, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE};



/* global variables */
SDL_Surface *screen;        //main drawing screen
SDL_Surface *Font_surface;  //font screen 
Uint32 _fgcolor, _bgcolor, _fontcolor;  //global color numbers
pid_t _pid;         //Don't bother with this 



/* function prototypes */
void initgraph(int *graphdriver,int *graphmode,char *pathtodriver);
void closegraph(void);
void setgraphmode(int gmode);
int  getgraphmode(void);
void restorecrtmode(void);
int  getmaxx(void);
int  getmaxy(void);
void putpixel(int x, int y, int color);
int  getpixel(int, int);
void setbkcolor(int color);
int  getbkcolor(void);
void setcolor(int color);
int  getcolor(void);
int getmaxcolor(void);
char* getdrivername(void);
char* getmodename(int mode_number);
int getmaxmode(void);
void detectgraph(int* graphdriver, int* graphmode);
void getmoderange(int graphdriver, int* lomode, int* himode);
int delay(float);
void setfontcolor(int color);
int getfontcolor(void);





/*** library specific functions - not for users ***/
void initialize_settings (void);
void mappixel(int, int);     //marks a pixel without updating screen
void clippixel(int *, int *); /* Clip pixel (x,y) to current
                                 screen size*/
void mapword(int,int,int);
void mapvword(int,int,int);
int colorrev(const Uint8);   // maps 0..255 8-bit color to 0..15 TC color
Uint8 colortrans(const int); // maps 0..15 TC color to 0..255 8-bit color
void ctrlbreak(void);        // To detect user interrupt    
void inthandler(int);        // clean up on user interrupt
void safe_update(int top, int left, int right, int bottom);
    /* update screen within boundary */

#define CHECK_INITIALIZATION\
    if (!getenv("LIBGRAPHICS_ACTIVE")) \
    { \
        fprintf(stderr, "*** The graphics system has not been initialized!\n"); \
        fprintf(stderr, "*** Call initgraph() before trying to use graphics functions.\n"); \
        exit(-1); \
    }

struct {int x;int y;}CP;

#include "grtext.h"
#include "shapes.h"
#include "polygon.h"

#ifdef __cplusplus
}
#endif      /* __cplusplus */


#endif      /* LIBGRAPH_H */

2 个答案:

答案 0 :(得分:1)

您的第一条错误消息是

  

circles.o :(。bss + 0x0):`screen'的多重定义

在你的代码中,当我写这篇文章时,没有任何东西叫做“屏幕”。

因此,问题似乎已经解决了。


编辑:既然你已经添加了(别人的)graphics.h的内容,作者对以下内容的无知就是问题的原因:

  

C ++98§7.5/ 7
  包含带括号的声明-seq 链接规范的形式   不影响所包含的声明是否为定义(3.1)。

所以指针变量声明有定义。

不幸的是,似乎不仅是该标题的作者,而且当前的C ++标准错误

  

C ++11§7.5/ 7:
  直接包含在 linkage-specification 中的声明被视为包含   extern说明符(7.1.1)用于确定声明的链接   名称和是否是定义。

根据该规范性文本,就好像每个指针变量都被声明为 extern因此会 只是一个声明(不是定义)。但是,即使在C ++ 11中也是非规范性的例子 显示意图,它是一个定义。

所有这一切,这对我来说也是新闻,而且我是老手。这似乎是公正的 标准中一个毫无意义的怪癖,一个不必要的陷阱。但可能是因为在C ++中 没有其他方法可以表达纯粹的声明与对象的定义。

干杯&amp;第h。,

答案 1 :(得分:1)

graphics.h包含以下几行:

/* global variables */ 
SDL_Surface *screen;        //main drawing screen 
SDL_Surface *Font_surface;  //font screen  
Uint32 _fgcolor, _bgcolor, _fontcolor;  //global color numbers 
pid_t _pid;         //Don't bother with this  

这有点奇怪,但是这个h文件会创建全局变量。这意味着,如果将此文件包含在多个.cpp文件中,则会出现多个定义错误。我不知道为什么这个h文件是用这种方式编写的,只有当graphics.h只包含在一个cpp文件中时才会链接程序。如果您可以更改此文件,请在每个全局变量之前添加extern关键字,并在某个.cpp文件中创建这些变量(如果需要)。