c++中的多个定义错误
Multiple Definition errors in c++
这是我在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 << "Menun 1. Midpoint Circle Drawing Algorithmn 2. Bresenham's Circle Drawing Algorithm n 3. Trigonometric Methodn";
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 Choicen";
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();
}
我在linux上使用graphics.h。基本程序运行良好。我得到的错误是
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 *screen
/* 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 */
graphics.h包含以下行:
<>之前/*全局变量*/SDL_Surface *屏幕;//主绘图屏幕SDL_Surface * Font_surface;//屏幕字体Uint32 _fgcolor, _bgcolor, _fontcolor;//全局颜色数pid_t _pid;//不用麻烦了之前这有点奇怪,但是这个h文件创建了全局变量。这意味着,如果将该文件包含到多个.cpp文件中,就会出现多个定义错误。我不知道为什么这个h文件是这样写的,只有将graphics.h包含到一个cpp文件中,程序才会被链接。如果您可以更改此文件,请在每个全局变量之前添加extern关键字,并在某些.cpp文件中创建这些变量(如果需要)。
您的第一个错误消息是
circles.o:(.bss+0x0): ' screen'的多重定义
在你的代码中,当我写这个的时候,没有什么叫做"screen"的东西。
因此,问题似乎已经解决了。
EDIT:既然您已经添加了(别人的)graphics.h
的内容,那么作者对以下内容的忽略是问题的原因:
c++ 98§7.5/7
链接规范的形式包含了用大括号括起来的声明-seq不影响所包含的声明是否是定义(3.1)。
所以指针变量声明有定义。
不幸的是,不仅头文件的作者,而且当前的c++标准都弄错了:
c++ 11§7.5/7:
直接包含在链接规范中的声明被视为包含extern
说明符(7.1.1),用于确定声明的链接名称以及是否为定义。
根据规范文本,好像每个指针变量都被声明为extern
,因此只是一个声明(而不是定义)。然而,即使在c++ 11的非规范的例子
说了这么多,这对我来说也是新闻,我是这方面的老手。这似乎是公正的标准中的一个毫无意义的怪癖,一个不必要的陷阱。但可能是因为在c++中没有其他的方法来表示对象的纯声明和定义。
干杯,hth。
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件