One or more multiply defined symbols found как исправить

I've been training to use object orientated programming in c++ but I keep getting this error: 1>main.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj 1>main.o...

I’ve been training to use object orientated programming in c++ but I keep getting this error:

1>main.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj
1>main.obj : error LNK2005: "int HEIGHT" (?HEIGHT@@3HA) already defined in GameObject.obj
1>Spaceship.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj
1>Spaceship.obj : error LNK2005: "int HEIGHT" (?HEIGHT@@3HA) already defined in GameObject.obj
1>C:Usersteddocumentsvisual studio 2010ProjectsfullSpaceDebugfullSpace.exe : fatal error LNK1169: one or more multiply defined symbols found

However to me, it seems that the entire code is written properly and the two ints are only mentioned in the Global header and all objects seem to be inheriting properly. However, like I just said, I’m a beginner in OOP so I really need an opinion : It is also worth mentioning that I am using allegro 5 to create a side shooter.

This is the code :

(main):

#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5allegro_ttf.h>
#include <allegro5allegro_audio.h>
#include <allegro5allegro_acodec.h>

#include <list>


#include "GameObject.h"
#include "Spaceship.h"
#include "Globals.h"



//controls

bool keys[] = {false, false, false, false, false};
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};

//globals
Spaceship *ship;

std::list <GameObject *> objects;
std::list <GameObject *>::iterator iter;
std::list <GameObject *>::iterator iter2;



//prototypes



//main function
int main(int argc, char **argv)
{
    //shell variables
    bool done = false;
    bool render = false;

    float gameTime = 0;
    int frames = 0;
    int gameFPS = 0;

    //project variables

    ship = new Spaceship();


    ALLEGRO_BITMAP *shipImage = NULL;
    ALLEGRO_BITMAP *cometImage= NULL;
    ALLEGRO_BITMAP *explImage = NULL;
    ALLEGRO_BITMAP *bgImage = NULL;
    ALLEGRO_BITMAP *mgImage = NULL;
    ALLEGRO_BITMAP *plImage = NULL;
    ALLEGRO_BITMAP *mgImage2 = NULL;
    ALLEGRO_BITMAP *fgImage = NULL;
    ALLEGRO_BITMAP *titleImage= NULL;
    ALLEGRO_BITMAP *lostImage = NULL;


    //allegro variables
    ALLEGRO_DISPLAY *display = NULL;
    ALLEGRO_EVENT_QUEUE *event_queue = NULL;
    ALLEGRO_TIMER *timer;
    ALLEGRO_FONT *font18;



    //initiate variables
    if(!al_init())
        return -1;

    display = al_create_display(WIDTH, HEIGHT);
    if(!display)
    return -1;

    //addon installation

    al_install_keyboard();
    al_init_image_addon();
    al_init_font_addon();
    al_init_ttf_addon();
    al_init_primitives_addon();
    al_install_audio();
    al_init_acodec_addon();

    //project init

    font18 = al_load_font("arial.ttf", 18, 0);
    al_reserve_samples(15);




    bgImage = al_load_bitmap("layer1.png");
    mgImage = al_load_bitmap("layer2.png");
    plImage = al_load_bitmap("starMG.png");
    mgImage2 = al_load_bitmap("layer3.png");
    fgImage = al_load_bitmap("layer4.png");




    shipImage = al_load_bitmap("spaceship.png");
    al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));



    cometImage = al_load_bitmap("asteroid-1-96.png");
    explImage = al_load_bitmap("explosion_3_40_128.png");

    titleImage = al_load_bitmap("Shooter_Title.png");
    lostImage = al_load_bitmap("Shooter_Lose.png");



    //object init
    ship->init(shipImage);


    //iter list
    objects.push_back(ship);


    srand(time(NULL));

    //timer init and startup

    event_queue = al_create_event_queue();
    timer = al_create_timer(1.0 / 60);

    al_register_event_source(event_queue, al_get_timer_event_source(timer));
    al_register_event_source(event_queue, al_get_keyboard_event_source());

    al_start_timer(timer);
    gameTime = al_current_time();

    while(!done)
    {
        ALLEGRO_EVENT ev;
        al_wait_for_event(event_queue, &ev);

        //input
        if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
        {
            switch(ev.keyboard.keycode)
            {
            case ALLEGRO_KEY_ESCAPE:
                done = true;
                break;
            case ALLEGRO_KEY_LEFT:
                keys[LEFT] = true;
                break;
            case ALLEGRO_KEY_RIGHT:
                keys[RIGHT] = true;
                break;
            case ALLEGRO_KEY_UP:
                keys[UP] = true;
                break;
            case ALLEGRO_KEY_DOWN:
                keys[DOWN] = true;
                break;
            case ALLEGRO_KEY_SPACE:
                keys[SPACE] = true;
                break;


            }
        } else if(ev.type == ALLEGRO_EVENT_KEY_UP)
        {
            switch(ev.keyboard.keycode)
            {
            case ALLEGRO_KEY_ESCAPE:
                done = true;
                break;
            case ALLEGRO_KEY_LEFT:
                keys[LEFT] = false;
                break;
            case ALLEGRO_KEY_RIGHT:
                keys[RIGHT] = false;
                break;
            case ALLEGRO_KEY_UP:
                keys[UP] = false;
                break;
            case ALLEGRO_KEY_DOWN:
                keys[DOWN] = false;
                break;
            case ALLEGRO_KEY_SPACE:
                keys[SPACE] = false;
                break;
            }
        }



        else if (ev.type == ALLEGRO_EVENT_TIMER)
        {
            render = true;

            //fps
            frames++;
            if(al_current_time() - gameTime >= 1)
            {
                gameTime = al_current_time();
                gameFPS = frames;
                frames = 0;
            }

            //shipUpdate

            if(keys[UP])
                ship ->moveUp();
            else if(keys[DOWN])
                ship ->moveDown();
            else
                ship->resetAnim(1);

            if(keys[LEFT])
                ship ->moveLeft();
            else if(keys[RIGHT])
                ship -> moveRight();
            else
                ship ->resetAnim(0);

        }
        //render

            if(render && al_is_event_queue_empty(event_queue))
            {
                render = false;

                //begin render
                for(iter = objects.begin(); iter != objects.end(); ++iter)
                    (*iter)->render();




                //Flip Buffers
                al_flip_display();
                al_clear_to_color(al_map_rgb(0,0,0));
            }
        }

                //destroy objects



        //visual objects
    al_destroy_bitmap(cometImage);
    for(iter = objects.begin(); iter != objects.end(); ++iter)
        (*iter)->destroy(shipImage);
        iter = objects.erase(iter);

    al_destroy_bitmap(explImage);
    al_destroy_bitmap(bgImage);
    al_destroy_bitmap(mgImage);
    al_destroy_bitmap(fgImage);
    al_destroy_bitmap(titleImage);
    al_destroy_bitmap(lostImage);

        //audio objects
    /*
    al_destroy_sample(shot);
    al_destroy_sample(boom);
    al_destroy_sample(song);
    al_destroy_sample_instance(songInstance);
    */


        //shell objects
    al_destroy_font(font18);
    al_destroy_timer(timer);
    al_destroy_event_queue(event_queue);
    al_destroy_display(display);

    return 0;
}

(Globals.h):

#pragma once

int WIDTH = 1024;
int HEIGHT = 800;

enum ID{PLAYER, ENEMY, BULLET, BORDER, MISC};
enum STATES{TITLE, PLAYING, LOST};

(GameObject.h):

#pragma once


#include "Globals.h"
#include <iostream>

#include <allegro5/allegro5.h>

#include <allegro5/allegro_primitives.h>



class GameObject
{
private:
    int ID;
    bool alive;
    bool collidable;

protected:
    float x;
    float y;

    float velX;
    float velY;

    int dirX;
    int dirY;

    int boundX;
    int boundY;

    int maxFrame;
    int curFrame;
    int frameCount;
    int frameDelay;
    int frameWidth;
    int frameHeight;
    int animationColumns;
    int animationDirection;

    ALLEGRO_BITMAP *image;

public:
    GameObject();
    void virtual destroy(ALLEGRO_BITMAP *image);

    void init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY);
    void virtual update();
    void virtual render();

    float getX() {return x;}
    float getY() {return y;}

    void setX(float x) {GameObject::x = x;}
    void setY(float y) {GameObject::y = y;}

    int getBoundX() {return boundX;}
    int getBoundY() {return boundY;}

    int getID() {return ID;}
    void setID(int ID) {GameObject::ID = ID;}

    bool getAlive() {return alive;}
    void setAlive(bool alive) {GameObject::alive = alive;}

    bool getCollidable() {return collidable;}
    void setCollidable(bool collidable) {GameObject::collidable = collidable;}

    bool checkCollisions(GameObject *otherObject);
    void virtual collided(int objectID);
    bool collidableCheck();
};

(GameObject.cpp):

#include "GameObject.h"

GameObject::GameObject()
{
    x = 0;
    y = 0;

    velX = 0;
    velY = 0;

    dirX = 0;
    dirY = 0;

    boundX = 0;
    boundY = 0;

    maxFrame = 0;
    curFrame = 0;
    frameCount = 0;
    frameDelay = 0;
    frameWidth = 0;
    frameHeight = 0;
    animationColumns = 0;
    animationDirection = 0;

    image = NULL;

    alive = true;
    collidable = true;

}

void GameObject::destroy(ALLEGRO_BITMAP *image)
{
    if(image != NULL)
        al_destroy_bitmap(image);

}
void GameObject::init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY)
{
    GameObject::x = x;
    GameObject::y = y;

    GameObject::velX = velX;
    GameObject::velY = velY;

    GameObject::dirX = dirX;
    GameObject::dirY = dirY;

    GameObject::boundX = boundX;
    GameObject::boundY = boundY;

}

void GameObject::update()
{
    x += velX*dirX;
    y += velY*dirY;
}

void GameObject::render()
{

}

bool GameObject::checkCollisions(GameObject *otherObject)
{
    float oX = otherObject->getX();
    float oY = otherObject->getY();

    int obX = otherObject->getBoundX();
    int obY = otherObject->getBoundY();

    if(x + boundX > oX - obX &&
       x - boundX < oX + obX &&
       y + boundY > oY - obY &&
       y - boundY < oY + obY
       )
       return true;
    else
       return false;
}

void GameObject::collided(int objectID)
{

}
bool GameObject::collidableCheck()
{
    return alive && collidable;
}

(SpaceShip.h):

#pragma once

#include "GameObject.h"

class Spaceship : public GameObject
{
private :
    int lives;
    int score;
    int animationRow;

public :
    Spaceship();

    void destroy(ALLEGRO_BITMAP *image);

    void init(ALLEGRO_BITMAP *image = NULL);

    void update();
    void render();

    void moveUp();
    void moveDown();
    void moveLeft();
    void moveRight();

    void resetAnim(int pos);

    int getLives(){return lives;}

    int getScore() {return score;}

    void looseLife() {lives--;}
    void addPoint() {score++;}

    void collide(int objectID);



};

(SpaceShip.cpp):

#include "Spaceship.h"

    Spaceship::Spaceship()
    {}

    void Spaceship::destroy(ALLEGRO_BITMAP *image)
    {
        GameObject::destroy(image);
    }
    void Spaceship::init(ALLEGRO_BITMAP *image)
    {
        GameObject::init(20, 200, 6, 6, 0, 0, 10, 12);

        setID(PLAYER);
        setAlive(true);

        lives = 3;
        score = 0;

        maxFrame = 3;
        curFrame = 0;
        frameWidth = 46;
        frameHeight = 41;
        animationColumns = 3;
        animationDirection = 1;

        animationRow = 1;

        if(image != NULL)
        {
            Spaceship::image = image;
        }
    }

    void Spaceship::update()
    {
        GameObject::update();
        if(x < 0)
            x=0;
        else if ( x > WIDTH)
            x = WIDTH;
        if(y < 0)
            y = 0;
        else if (y > HEIGHT)
            y = HEIGHT;
    }
    void Spaceship::render()
    {
        GameObject::render();

        int fx = (curFrame % animationColumns) *frameWidth;
        int fy = animationRow *frameHeight;

        al_draw_bitmap_region(image, fx, fy, frameWidth, frameHeight,
            x - frameWidth /2, y - frameHeight /2, 0);

    }

    void Spaceship::moveUp()
    {
        animationRow = 0;
        dirY = -1;

    }
    void Spaceship::moveDown()
    {
        animationRow = 2;
        dirY = 1;
    }
    void Spaceship::moveLeft()
    {
        curFrame = 2;
        dirX = -1;
    }
    void Spaceship::moveRight()
    {
        curFrame = 1;
        dirX = 1;
    }

    void Spaceship::resetAnim(int pos)
    {
        if(pos == 1)
        {
            animationRow = 1;
            dirY = 0;
        }
        else
        {
            curFrame = 0;
            dirX = 0;
        }
    }

    void Spaceship::collide(int objectID)
    {
        if(objectID == ENEMY)
            lives--;

    }

Асурус

2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

1

05.07.2013, 09:51. Показов 4503. Ответов 16

Метки нет (Все метки)


Доброго всем времени суток! Никак не могу разобраться в чём дело… Помогите пожалуйста!
stdafx.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma once
 
#include "targetver.h"
 
#include <stdio.h>
#include <tchar.h>
 
#include <conio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
#include <Windows.h>

Get_String_Getche.h

C++
1
2
3
#include "stdafx.h"
 
void get_str(char* str);

Very_Long_Number.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "stdafx.h"
#include "Get_String_Getche.h"
 
extern const int SZ = 1000;
enum posneg{pos, neg};
 
class very_l_numb
{
private:
    char number[SZ];
    int numb_len;
    int signs_after_comma;
    posneg pn;
    very_l_numb mult_on_10(const very_l_numb);
    very_l_numb mult_on_digit(const int);
    void ld_to_str(const long double, char*);
public:
    very_l_numb()
    {
        number[0] = '';
        numb_len = 0;
        signs_after_comma = 0;
        pn = pos;
    }
    very_l_numb(const char str[])
    {
        int count_len = 0;
        int sign = 0;
        int slen = strlen(str);
        signs_after_comma = 0;
        for(int j = 0; j < slen; j++)
        {
            if(str[j] == ',')
            {
                if(signs_after_comma != 0)
                {
                    cout << "Ошибка, запятая уже была отмечена! Конструктор номер два. " << endl;
                    system("pause");
                    exit(0);
                }
                else
                    signs_after_comma = j;
            }
            else
            {
                
                if(str[j] >= '0' && str[j] <= '9')
                {
                    number[j] = str[j];
                    count_len++;
                }
                else if(str[j] == '+' || str[j] == '-')
                {
                    if(sign == 0)
                        sign = 1;
                    else
                    {
                        cout << "В числе присутствует больше одного знака! Конструктор номер два." << endl;
                        system("pause");
                        exit(0);
                    }
                }
                else
                {
                    cout << "В числе обнаружены инородные символы! Конструктор номер два." << endl;
                    system("pause");
                    exit(0);
                }
            }
        }
        number[numb_len] = '';
        strrev(number);
        numb_len = count_len;
        if(str[slen - 1] == '-')
            pn = neg;
        else
            pn = pos;
    }
    very_l_numb(const long double ld)
    {
        char str[SZ];
        ld_to_str(ld, str);
        very_l_numb temp(str);
        strcpy(number, temp.number);
        numb_len = temp.numb_len;
        signs_after_comma = temp.signs_after_comma;
        pn = temp.pn;
    }
    void show_numb();
    void get_numb();
    very_l_numb operator *(very_l_numb);
    very_l_numb operator +(very_l_numb);
    very_l_numb operator /(very_l_numb);
    very_l_numb operator -(very_l_numb);
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "stdafx.h"
#include "Very_Long_Number.h"
 
extern const int SZ;
 
int _tmain(int argc, _TCHAR* argv[])
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    setlocale(LC_ALL, "rus");
    very_l_numb test((long double)10);
    test.show_numb();
    system("pause");
    return 0;
}

Get_String_Getche.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "stdafx.h"
#include "Get_String_Getche.h"
 
extern const int SZ;
 
void get_str(char* str)
{
    int count = 0;
    char ch = 8;
    do
    {
        if(count == SZ)
        {
            cout << endl << "Строка может содержать только " << SZ - 1 << " символов." << endl
                << "Попрубуйте ещё раз." << endl;
            count = 0;
        }
        *(str + count++) = getche();
        if(*(str + count - 1) == 8)
        {
            if(count != 1)
            {
                cout << " " << ch;;
                count -= 2;
            }
            else
                count--;
        }
    }while(*(str + (count - 1)) != 'r');
    str[count - 1] = 'x0';
    cout << endl;
}

Very_Long_Number.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "stdafx.h"
#include "Very_Long_Number.h"
 
void very_l_numb::ld_to_str(const long double ld, char* str)
{
    double d1;
    d1 = ld;
    int j = 0, i, a = 0;
    while(d1 > 1)
    {
        d1 /= 10;
        j++;
    }
    while(d1 != 0)
    {
        d1 *= 10;
        i = d1;
        d1 -= i;
        if(a == j && d1 != 0)
            str[a++] = ',';
        else
            str[a++] = i + '0';
    }
    str[a] = '';
}
 
void very_l_numb::show_numb()
{
    if(signs_after_comma == numb_len)
        cout << '0';
    for(int j = numb_len; j > 0 + 1; j--)
    {
        if(j == signs_after_comma)
            cout << ',';
        cout << number[j - 1];
    }
}

Выдаёт вот это: fatal error LNK1169: one or more multiply defined symbols found

Добавлено через 18 минут
Эта проблема возникла после подключения Very_Long_Number.cpp

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

08.07.2013, 11:17

 [ТС]

2

Help please!

Добавлено через 22 часа 21 минуту
Мне кажется проблема где-то со включениями… так как ошибку компилятор выдал после включения Very_Long_Number.cpp
Отзавитесь кто-нибудь…

Добавлено через 1 час 23 минуты
Что это вообще может значить…

Добавлено через 10 часов 12 минут
Мне надо отлаживать то, что я тут понаписал… застрял я на этой ошибке.



0



alsav22

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

09.07.2013, 06:30

3

Это из-за:

C++
1
extern const int SZ = 1000;

в Very_Long_Number.h. Он подключается в двух файлах (main() и Very_Long_Number.cpp), отсюда множетсвенное определение.



1



2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

09.07.2013, 06:43

 [ТС]

4

Спасибо… кажется разобрался.



0



alsav22

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

09.07.2013, 06:53

5

Только как от этого избавиться (в студии) я не занаю, кроме как убрать из файлов все объявленя/определения SZ и прописать в Get_String_Getche.h:

C++
1
#define SZ 1000

Добавлено через 2 минуты
И ещё, рекомендуется using namespace std; помещать, в файле, после всех инклудов.



0



Асурус

2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

09.07.2013, 07:06

 [ТС]

6

Я перенёс

C++
1
#include "Very_Long_Number.h"

в «stdafx.h» и проблема решена.



0



Tulosba

09.07.2013, 07:33

Не по теме:

Цитата
Сообщение от alsav22
Посмотреть сообщение

И ещё, рекомендуется using namespace std; помещать, в файле, после всех инклудов.

Рекомендуется не использовать данную запись в принципе.



0



alsav22

09.07.2013, 07:44

Не по теме:

Цитата
Сообщение от Tulosba
Посмотреть сообщение

Рекомендуется не использовать данную запись в принципе.

В заголовочных файлах.
Герб Саттер. Решение сложных задач на C++. Поспорьте с профессионалом.



0



alsav22

09.07.2013, 07:54



0



alsav22

5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

09.07.2013, 07:59

10

Цитата
Сообщение от Асурус
Посмотреть сообщение

Я перенёс

C++
1
#include "Very_Long_Number.h"

в «stdafx.h» и проблема решена.

Откуда что перенесли? Не пойму, как это может помочь, если stdafx.h тоже подключен к нескольким .cpp?



0



Асурус

2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

09.07.2013, 08:04

 [ТС]

11

C++
1
#pragma once

— кажется эта директива служит защитой от множественного включения



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

09.07.2013, 08:06

12

А что конкретно перенесли? Откуда?



0



Асурус

2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

09.07.2013, 08:10

 [ТС]

13

C++
1
#include "Very_Long_Number.h"

— удалил из файла с main(), и из «Very_Long_Number.cpp», и записал в «stdafx.h»



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

09.07.2013, 08:16

14

У меня ошибка остаётся. Не понятно, почему у вас нет. Весь проект может выложить?



0



Асурус

2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

09.07.2013, 08:27

 [ТС]

15

У меня там много и других ошибок… вот проект:
Get_String_Getche.h

C++
1
2
3
#include "stdafx.h"
 
void get_str(char* str);

stdafx.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
 
#pragma once
 
#include "targetver.h"
 
#include <stdio.h>
#include <tchar.h>
 
#include <conio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <process.h>
using namespace std;
#include <Windows.h>
 
#include "Very_Long_Number.h"
// TODO: reference additional headers your program requires here

Very_Long_Number.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "stdafx.h"
#include "Get_String_Getche.h"
 
extern const int SZ = 1000;
enum posneg{pos, neg};
 
class very_l_numb
{
private:
    char number[SZ];
    int numb_len;
    int signs_after_comma;
    posneg pn;
    very_l_numb mult_on_10(const very_l_numb);
    very_l_numb mult_on_digit(const int);
    void ld_to_str(const long double, char*);
public:
    very_l_numb()
    {
        number[0] = '';
        numb_len = 0;
        signs_after_comma = 0;
        pn = pos;
    }
    very_l_numb(const char str[])
    {
        int count_len = 0;
        int sign = 0;
        int slen = strlen(str);
        signs_after_comma = 0;
        for(int j = 0; j < slen; j++)
        {
            if(str[j] == ',')
            {
                if(signs_after_comma != 0)
                {
                    cout << "Ошибка, запятая уже была отмечена! Конструктор номер два. " << endl;
                    system("pause");
                    exit(0);
                }
                else
                    signs_after_comma = j;
            }
            else
            {
                
                if(str[j] >= '0' && str[j] <= '9')
                {
                    number[j] = str[j];
                    count_len++;
                }
                else if(str[j] == '+' || str[j] == '-')
                {
                    if(sign == 0)
                        sign = 1;
                    else
                    {
                        cout << "В числе присутствует больше одного знака! Конструктор номер два." << endl;
                        system("pause");
                        exit(0);
                    }
                }
                else
                {
                    cout << "В числе обнаружены инородные символы! Конструктор номер два." << endl;
                    system("pause");
                    exit(0);
                }
            }
        }
        number[numb_len] = '';
        strrev(number);
        numb_len = count_len;
        if(str[slen - 1] == '-')
            pn = neg;
        else
            pn = pos;
    }
    very_l_numb(const long double ld)
    {
        char str[SZ];
        ld_to_str(ld, str);
        very_l_numb temp(str);
        strcpy(number, temp.number);
        numb_len = temp.numb_len;
        signs_after_comma = temp.signs_after_comma;
        pn = temp.pn;
    }
    void show_numb();
    void get_numb();
    very_l_numb operator *(very_l_numb);
    very_l_numb operator +(very_l_numb);
    very_l_numb operator /(very_l_numb);
    very_l_numb operator -(very_l_numb);
};

Class_Very_Long_Number.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Class_Very_Long_Number.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
//#include "Very_Long_Number.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    setlocale(LC_ALL, "rus");
//  very_l_numb test((long double)10);
//  test.show_numb();
    system("pause");
    return 0;
}

Get_String_Getche.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "stdafx.h"
#include "Get_String_Getche.h"
 
//extern const int SZ;
 
void get_str(char* str)
{
    int count = 0;
    char ch = 8;
    do
    {
        if(count == SZ)
        {
            cout << endl << "Строка может содержать только " << SZ - 1 << " символов." << endl
                << "Попробуйте ещё раз." << endl;
            count = 0;
        }
        *(str + count++) = getche();
        if(*(str + count - 1) == 8)
        {
            if(count != 1)
            {
                cout << " " << ch;;
                count -= 2;
            }
            else
                count--;
        }
    }while(*(str + (count - 1)) != 'r');
    str[count - 1] = 'x0';
    cout << endl;
}

Very_Long_Number.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "stdafx.h"
//#include "Very_Long_Number.h"
 
void very_l_numb::ld_to_str(const long double ld, char* str)
{
    double d1;
    d1 = ld;
    int j = 0, i, a = 0;
    while(d1 >= 1)
    {
        d1 /= 10;
        j++;
    }
    while(d1 != 0)
    {
        d1 *= 10;
        i = d1;
        d1 -= i;
        if(a == j && d1 != 0)
            str[a++] = ',';
        else
            str[a++] = i + '0';
    }
    str[a] = '';
}
 
void very_l_numb::show_numb()
{
    if(signs_after_comma == numb_len)
        cout << '0';
    for(int j = numb_len; j > 0 + 1; j--)
    {
        if(j == signs_after_comma)
            cout << ',';
        cout << number[j - 1];
    }
}



0



5493 / 4888 / 831

Регистрация: 04.06.2011

Сообщений: 13,587

09.07.2013, 08:42

16

Цитата
Сообщение от Асурус
Посмотреть сообщение

вот проект:

Я имел ввиду файлы студии.

Добавлено через 54 секунды

Цитата
Сообщение от Асурус
Посмотреть сообщение

У меня там много и других ошибок…

Может до этой просто не доходит?

Добавлено через 6 минут
У меня, как раз, других ошибок нет (предупреждения есть), только эта.



0



2 / 2 / 2

Регистрация: 27.07.2012

Сообщений: 40

09.07.2013, 08:58

 [ТС]

17

Не, теперь всё в норме, я закоментировал вызовы функций с ошибками, всё выполняется.

Добавлено через 1 минуту
Что-то не хочет загружаться…

Добавлено через 7 минут
Не… извиняюсь… проэкт не загружается… не хочет с компа скачивать, что то за ошибку показывает…



0




Почему происходит multiply defined symbols

От:

TheAteist

 
Дата:  07.06.09 11:54
Оценка:

При компиляции происходят ошибки:
1 — error LNK2005: _assetType already defined in customer.obj
2 — fatal error LNK1169: one or more multiply defined symbols found
Погуглив я понял, что компилятор вставляет 2 раз вот это

const char* assetType[] = {"apartment", "shop", "house"};

но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз
Почему тогда происходит ошибка и как ее исправить?
Большое спасибо.

//main.c

#include "customer.h"

void main()
{
}

//customer.h

#ifndef _CUSTOMER_H_
#define _CUSTOMER_H_
const char* assetType[] = {"apartment", "shop", "house"};
void func();
#endif

//customer.c

#include "customer.h"

void func()
{
    int i;
}


Re: Почему происходит multiply defined symbols

От:

Caracrist

https://1pwd.org/
Дата:  07.06.09 12:10
Оценка:

-2


Re[2]: Почему происходит multiply defined symbols

От:

Caracrist

https://1pwd.org/
Дата:  07.06.09 12:26
Оценка:

+1

Здравствуйте, Caracrist, Вы писали:

C>this ?

C>

C>#pragma once
C>


это я прогнал

missing static…

static const char* assetType[] = {"apartment", "shop", "house"};


Re: Почему происходит multiply defined symbols

От:

andrey.desman

Россия

 
Дата:  07.06.09 12:45
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз

Да, один раз, но в каждую единицу трансляции (файл .c / .cpp).
Этот так называемый include guard помогает в ситуации, когда заголовок (файл .h) включается два или более раза в одну единицу трансляции.

TA>Почему тогда происходит ошибка и как ее исправить?

Так как символ глобальный, то он «виден» и из других единиц трансляции. Но так как заголовок включен в оба сишника, то создается два символа с одним и тем же именем, чего линкер очень не любит.
Либо добавь «static», тогда в каждом сишнике будет своя копия этого массива и конфликта имен не будет.
Либо, определение в какой-нибудь один сишник, а в заголовок только объявление. Тогда будет существовать лишь одна копия этого массива.


Re: Почему происходит multiply defined symbols

От:

Alexey F

 
Дата:  07.06.09 12:51
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>При компиляции происходят ошибки:

TA>1 — error LNK2005: _assetType already defined in customer.obj
TA>2 — fatal error LNK1169: one or more multiply defined symbols found
TA>Погуглив я понял, что компилятор вставляет 2 раз вот это
TA>

TA>const char* assetType[] = {"apartment", "shop", "house"};
TA>

В дополнение к данным выше ответам:

const char* const assetType[] = {"apartment", "shop", "house"};

Так тоже будет работать (подразумевается внутреннее связывание).

TA>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз

Верно. По одному разу в каждый файл, который подключил customer.h.

P.S. Если нет желания делать массив константным или внутренним для каждой единицы трансляции, то только так:
в заголовке его объявляем с extern, а определяем в отдельном .c/.cpp файле


Re[2]: Почему происходит multiply defined symbols

От:

TheAteist

 
Дата:  07.06.09 20:01
Оценка:

Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, TheAteist, Вы писали:


TA>>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз

AD>Да, один раз, но в каждую единицу трансляции (файл .c / .cpp).
AD>Этот так называемый include guard помогает в ситуации, когда заголовок (файл .h) включается два или более раза в одну единицу трансляции.
1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?
2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?

TA>>Почему тогда происходит ошибка и как ее исправить?

AD>Так как символ глобальный, то он «виден» и из других единиц трансляции. Но так как заголовок включен в оба сишника, то создается два символа с одним и тем же именем, чего линкер очень не любит.
AD>Либо добавь «static», тогда в каждом сишнике будет своя копия этого массива и конфликта имен не будет.
Своя копия означает
AD>Либо, определение в какой-нибудь один сишник, а в заголовок только объявление. Тогда будет существовать лишь одна копия этого массива.


Re[2]: Почему происходит multiply defined symbols

От:

TheAteist

 
Дата:  07.06.09 20:02
Оценка:

Здравствуйте, Alexey F, Вы писали:

AF>Здравствуйте, TheAteist, Вы писали:


TA>>При компиляции происходят ошибки:

TA>>1 — error LNK2005: _assetType already defined in customer.obj
TA>>2 — fatal error LNK1169: one or more multiply defined symbols found
TA>>Погуглив я понял, что компилятор вставляет 2 раз вот это
TA>>

TA>>const char* assetType[] = {"apartment", "shop", "house"};
TA>>



AF>В дополнение к данным выше ответам:

AF>

AF>const char* const assetType[] = {"apartment", "shop", "house"};
AF>


AF>Так тоже будет работать (подразумевается внутреннее связывание).

TA>>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз

AF>Верно. По одному разу в каждый файл, который подключил customer.h.
1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?
2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?

AF>P.S. Если нет желания делать массив константным или внутренним для каждой единицы трансляции, то только так:

AF>в заголовке его объявляем с extern, а определяем в отдельном .c/.cpp файле


Re[3]: Почему происходит multiply defined symbols

От:

Kirikaza

Россия

kirikaza.ru
Дата:  07.06.09 20:35
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?

TA>2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?

#include «x.h» лучше рассматривать как «вставить в этом месте содержимое файла x.h».

Пусть есть файл x.h:

#ifndef X_H
#define X_H
...
#endif

Если файл x.h вставлен дважды в некий C-файл

#include "x.h"
#include "x.h"

то получается вот так:

#ifndef X_H
#define X_H
...
#endif
#ifndef X_H
#define X_H
...
#endif

При этом первый #ifndef сработает, т.к. X_H ещё не определена, и определит X_H. А второй #ifndef не сработает, т.к. X_H уже определена.

Когда происходит компиляция, препроцессор берёт C-файл выполняет вот эту подстановку и оставляет код внутри первого #if и выкидывает внутри второго. Затем полученный код отдаётся компилятору, который компилирует и получает объектный файл. Затем берётся второй C-файл и для него независимо от первого C-файла процедура повторяется заново (т.е. в самом начале обработки препроцессором второго C-файла X_H никем не была определена). Когда все объектные файлы получены, они все линкуются (связываются) в один.

В твоём случае H-файл включается по разу в каждый подключающий его C-файл. Объектные файлы получаются с копиями того массива, но компилятор при создании каждого из них об этом не знает. А вот линковщик (linker) видит две вещи с одним именем в одной глобальной области и пугается, т.к. для обеих из них есть определение.

Т.е. H-файлы сами по себе непосредственно не обрабатываются. Всё исходит от C-файлов. Ну а что делать — тебе уже сказали.

P.S.: На самом деле компиляторы данный процесс обычно оптимизируют, но поведение такое сохраняют.


Re[3]: Почему происходит multiply defined symbols

От:

Alexey F

 
Дата:  07.06.09 20:46
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?

include-guard (те самые #ifndef/#define/#endif) нужны для других целей. А, именно, для предотвращения включения текста включаемого файла дважды в одну и ту же единицу трансляции. Такое может произойти, например, когда файл X.h включает файл Y.h, а потом включает файл Z.h, который, в свою очередь, снова подключает Y.h. Без include-guard’ов получили бы множество ошибок переопределения.

TA>2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?

Сэкономить место на диске? Нет, скорее сэкономить время и нервы программиста, избавляя его от перебивания одинаковых строк из файла в файл
В Вашем случае решение ситуации в смене связывания объявляемому массиву. Как это сделать — уже описали выше (static, const, extern).

P.S. Ещё безымянные namespace могут решить проблему, но по мне лучше уж const или вынос определения в отдельную единицу трансляции.


Re[4]: Почему происходит multiply defined symbols

От:

TheAteist

 
Дата:  07.06.09 21:19
Оценка:

Здравствуйте, Kirikaza, Вы писали:

K>Здравствуйте, TheAteist, Вы писали:


TA>>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?

TA>>2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?

K>#include «x.h» лучше рассматривать как «вставить в этом месте содержимое файла x.h».


K>Пусть есть файл x.h:

K>

#ifndef X_H
K>#define X_H
K>...
K>#endif
K>



K>Если файл x.h вставлен дважды в некий C-файл

K>

#include "x.h"
K>#include "x.h"


K>то получается вот так:
K>

#ifndef X_H
K>#define X_H
K>...
K>#endif
K>#ifndef X_H
K>#define X_H
K>...
K>#endif


K>При этом первый #ifndef сработает, т.к. X_H ещё не определена, и определит X_H. А второй #ifndef не сработает, т.к. X_H уже определена.

K>Когда происходит компиляция, препроцессор берёт C-файл выполняет вот эту подстановку и оставляет код внутри первого #if и выкидывает внутри второго. Затем полученный код отдаётся компилятору, который компилирует и получает объектный файл. Затем берётся второй C-файл и для него независимо от первого C-файла процедура повторяется заново (т.е. в самом начале обработки препроцессором второго C-файла X_H никем не была определена). Когда все объектные файлы получены, они все линкуются (связываются) в один.


K>В твоём случае H-файл включается по разу в каждый подключающий его C-файл. Объектные файлы получаются с копиями того массива, но компилятор при создании каждого из них об этом не знает. А вот линковщик (linker) видит две вещи с одним именем в одной глобальной области и пугается, т.к. для обеих из них есть определение.

Это я понял. Я не понял почему только на массив все «крики», а не, скажем на «typedef enum{eBuy, eSell, eRent} assetAction;» который у меня определяется под массивом. Или на определений функций, которые и они находятся в том же customer.h и все в #ifndef.
K>Т.е. H-файлы сами по себе непосредственно не обрабатываются. Всё исходит от C-файлов. Ну а что делать — тебе уже сказали.

K>P.S.: На самом деле компиляторы данный процесс обычно оптимизируют, но поведение такое сохраняют.


Re[4]: Почему происходит multiply defined symbols

От:

TheAteist

 
Дата:  07.06.09 21:21
Оценка:

Здравствуйте, Alexey F, Вы писали:

AF>Здравствуйте, TheAteist, Вы писали:


TA>>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?


AF>include-guard (те самые #ifndef/#define/#endif) нужны для других целей. А, именно, для предотвращения включения текста включаемого файла дважды в одну и ту же единицу трансляции. Такое может произойти, например, когда файл X.h включает файл Y.h, а потом включает файл Z.h, который, в свою очередь, снова подключает Y.h. Без include-guard’ов получили бы множество ошибок переопределения.

Это я понял. Я не понял почему только на массив все «крики», а не, скажем на «typedef enum{eBuy, eSell, eRent} assetAction;» который у меня определяется под массивом. Или на определений функций, которые и они находятся в том же customer.h и все в #ifndef.
TA>>2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?
AF>Сэкономить место на диске? Нет, скорее сэкономить время и нервы программиста, избавляя его от перебивания одинаковых строк из файла в файл
AF>В Вашем случае решение ситуации в смене связывания объявляемому массиву. Как это сделать — уже описали выше (static, const, extern).

AF>P.S. Ещё безымянные namespace могут решить проблему, но по мне лучше уж const или вынос определения в отдельную единицу трансляции.


Re[5]: Почему происходит multiply defined symbols

От:

Alexey F

 
Дата:  07.06.09 22:36
Оценка:

Здравствуйте, TheAteist, Вы писали:

[offtop]
Зачем дублируете ответы? И оверквотинг лишний.
[/offtop]

TA>Это я понял. Я не понял почему только на массив все «крики», а не, скажем на «typedef enum{eBuy, eSell, eRent} assetAction;» который у меня определяется под массивом. Или на определений функций, которые и они находятся в том же customer.h и все в #ifndef.

Здесь разные вещи. С помощью typedef enum Вы определяете тип.
А

const char* assetType[] = {"apartment", "shop", "house"};

определяет переменную, которая уже имеет по-умолчанию внешнее связывание, т.е. учавствует при линковке. Соответственно, получаются две переменные с одним и тем же именем, определённые в двух разных файлах трансляции. Какую прикажете выбирать линкеру?
Иллюстрация более наглядного случая (чтобы было понятно, почему линковщик не имеет право плюнуть на это и выбрать одно из определений):

// 1.cpp
int val = 0; // фактически, эта строка могла быть в h-файле

// 2.cpp
int val = 42; // фактически, эта строка могла быть в h-файле

// 3.cpp
extern int val;
...
    printf ( "%d", val ); // Ой! А какая val?

P.S. Даже если тела Ваших массивов одинаковы, для линкера — это две переменных с одним и тем же именем.


Re: Почему происходит multiply defined symbols

От:

LaptevVV

Россия

 
Дата:  08.06.09 07:29
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>При компиляции происходят ошибки:

TA>1 — error LNK2005: _assetType already defined in customer.obj
TA>2 — fatal error LNK1169: one or more multiply defined symbols found
TA>Погуглив я понял, что компилятор вставляет 2 раз вот это
TA>

TA>const char* assetType[] = {"apartment", "shop", "house"};
TA>


TA>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз
TA>Почему тогда происходит ошибка и как ее исправить?
TA>Большое спасибо.

Я обычно делаю так:
1. Все переменные и константы, которые мне нужны в нескольких единицах трансляции, выношу в отдельный файл вроде variable.cpp
2. Пишу variable.h, в котором делаю ОБЪЯВЛЕНИЯ

extern переменная/константа;

3. К единицам трансляции подключаю variable.h

Хочешь быть счастливым — будь им!
Без булдырабыз!!!


Re[3]: Почему происходит multiply defined symbols

От:

рыбак

 
Дата:  08.06.09 10:49
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?

#ifndef (или #pragma once) защищает от двойного включения заголовка (.h) в одну единицу компиляции (.cpp). То есть для удачной компиляции.
У тебя же ошибка линковки. Это когда в двух разных единицах компиляции (.cpp) получился одинаковый символ.


Re[2]: Почему происходит multiply defined symbols

От: Аноним

 
Дата:  08.06.09 11:15
Оценка:

Здравствуйте, LaptevVV, Вы писали:

LVV>Я обычно делаю так:

LVV>1. Все переменные и константы, которые мне нужны в нескольких единицах трансляции, выношу в отдельный файл вроде variable.cpp

А все классы, которые нужны в нескольких единицах трансляции выносишь в файл вроде class.cpp? Одно непонятно, откуда при таком подходе появляется больше одной единицы трансляции.


Re[5]: Почему происходит multiply defined symbols

От:

Юрий Жмеренецкий

ICQ 380412032
Дата:  08.06.09 11:40
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>Я не понял почему только на массив все «крики», а не, скажем на «typedef enum{eBuy, eSell, eRent} assetAction;» который у меня определяется под массивом.

Это enumerator-definition, а для таких (и некоторых других) определений есть список условий, при соблюдении которых уникальность (определения в пределах программы) не является обязательной (3.2/5).

TA>Или на определений функций, которые и они находятся в том же customer.h и все в #ifndef.

В приведенном выше коде в файле ‘customer.h’ находится объявление функции (func), а не определение.

PS: Поищи по «One definition rule», здесь это неоднократно обсуждалось.


Re[6]: Почему происходит multiply defined symbols

От:

TheAteist

 
Дата:  08.06.09 17:28
Оценка:

Здравствуйте, Alexey F, Вы писали:

AF>P.S. Даже если тела Ваших массивов одинаковы, для линкера — это две переменных с одним и тем же именем.

Кажется я понял
Значит премерно вот так получается, да?

//main.obj
const char* assetType[] = {"apartment", "shop", "house"};
void func();
void main()
{
}
//customer.obj 
const char* assetType[] = {"apartment", "shop", "house"};
void func();
void func()
{
    int i;
}


Re[3]: Почему происходит multiply defined symbols

От:

LaptevVV

Россия

 
Дата:  09.06.09 05:18
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, LaptevVV, Вы писали:


LVV>>Я обычно делаю так:

LVV>>1. Все переменные и константы, которые мне нужны в нескольких единицах трансляции, выношу в отдельный файл вроде variable.cpp

А>А все классы, которые нужны в нескольких единицах трансляции выносишь в файл вроде class.cpp? Одно непонятно, откуда при таком подходе появляется больше одной единицы трансляции.

Зачем-же? Речь идет не о классах, а об общих переменных. Если они требуются, конечно.

Каждый класс — это class.h и class.cpp
Можно в class.h собрать несколько классов, но лучше разделить.

Хочешь быть счастливым — будь им!
Без булдырабыз!!!


Re[4]: Почему происходит multiply defined symbols

От: Аноним

 
Дата:  09.06.09 11:23
Оценка:

Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, LaptevVV, Вы писали:


LVV>Зачем-же? Речь идет не о классах, а об общих переменных. Если они требуются, конечно.


LVV>Каждый класс — это class.h и class.cpp

LVV>Можно в class.h собрать несколько классов, но лучше разделить.

А почему лучше их разделить и почему нельзя эти рассуждения применить к общим переменным?

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Содержание

  1. Fatal error lnk1169 one or more multiply defined symbols found
  2. Asked by:
  3. Question
  4. All replies
  5. Fatal error lnk1169 one or more multiply defined symbols found
  6. Asked by:
  7. Question
  8. All replies
  9. Fatal error lnk1169 one or more multiply defined symbols found
  10. Fatal error lnk1169 one or more multiply defined symbols found
  11. Answered by:
  12. Question
  13. Fatal error lnk1169 one or more multiply defined symbols found

Fatal error lnk1169 one or more multiply defined symbols found

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Asked by:

Question

fatal error LNK1169: one or more multiply defined symbols found

How can i fix this error?

Welcome to MSDN forum.

>> Fatal error LNK1169

## This error is preceded by error LNK2005. Generally, this error means you have broken the one definition rule, which allows only one definition for any used template, function, type, or object in a given object file, and only one definition across the entire executable for externally visible objects or functions.

Do you meet this error when you are running test project? And does your project build/debug well without any error?

According to the official document, You could refer to below possible causes and for solutions please refer to this link Possible causes and solutions.

(1) Check if one of your header file defines a variable and maybe include this header file in more than one source file in your project.

(2) This error can occur when a header file defines a function that isn’t inline. If you include this header file in more than one source file, you get multiple definitions of the function in the executable.

(3) This error can also occur if you define member functions outside the class declaration in a header file.

(4) This error can occur if you link more than one version of the standard library or CRT.

(5) This error can occur if you mix use of static and dynamic libraries when you use the /clr option

(6) This error can occur if the symbol is a packaged function (created by compiling with /Gy ) and it was included in more than one file, but was changed between compilations.

(7) This error can occur if the symbol is defined differently in two member objects in different libraries, and both member objects are used. One way to fix this issue when the libraries are statically linked is to use the member object from only one library, and include that library first on the linker command line.

(8) This error can occur if an extern const variable is defined twice, and has a different value in each definition.

(9) This error can occur if you use uuid.lib in combination with other .lib files that define GUIDs (for example, oledb.lib and adsiid.lib).

There are some similar issues and maybe helpful.

Источник

Fatal error lnk1169 one or more multiply defined symbols found

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Asked by:

Question

fatal error LNK1169: one or more multiply defined symbols found

How can i fix this error?

Welcome to MSDN forum.

>> Fatal error LNK1169

## This error is preceded by error LNK2005. Generally, this error means you have broken the one definition rule, which allows only one definition for any used template, function, type, or object in a given object file, and only one definition across the entire executable for externally visible objects or functions.

Do you meet this error when you are running test project? And does your project build/debug well without any error?

According to the official document, You could refer to below possible causes and for solutions please refer to this link Possible causes and solutions.

(1) Check if one of your header file defines a variable and maybe include this header file in more than one source file in your project.

(2) This error can occur when a header file defines a function that isn’t inline. If you include this header file in more than one source file, you get multiple definitions of the function in the executable.

(3) This error can also occur if you define member functions outside the class declaration in a header file.

(4) This error can occur if you link more than one version of the standard library or CRT.

(5) This error can occur if you mix use of static and dynamic libraries when you use the /clr option

(6) This error can occur if the symbol is a packaged function (created by compiling with /Gy ) and it was included in more than one file, but was changed between compilations.

(7) This error can occur if the symbol is defined differently in two member objects in different libraries, and both member objects are used. One way to fix this issue when the libraries are statically linked is to use the member object from only one library, and include that library first on the linker command line.

(8) This error can occur if an extern const variable is defined twice, and has a different value in each definition.

(9) This error can occur if you use uuid.lib in combination with other .lib files that define GUIDs (for example, oledb.lib and adsiid.lib).

There are some similar issues and maybe helpful.

Источник

Fatal error lnk1169 one or more multiply defined symbols found

Write your question here. Hi, it is me again. I am getting this error and cannot figure out what I am doing wrong. It is in visual studios 2013 again BTW.

[#include «stdafx.h» // Precompiled header
#include «iostream» // Input and output stream
using namespace std; // Meaning you don’t have to put std:: before cout Last edited on

can you use code tags please?

for example, you prototype:
int squareIntegers();

but you call it like this:
squareIntegers(22)

you also do not need prototype declarations if you’re implementing them before you call them.
i.e. delete these:

why are you doing calculations and then return zero?

edit:
you also do not need this either:

are wrong, and not even needed.

I did it because I cannot return both answer1 and answer2 twice.

You need to read that link i pasted on functions.

So, I read it but and why are
[int squareIntegers(); // Function Prototype
double squareDouble();
float squareFloat();], wrong. They are function prototypes.

Also, I get an error saying to include «stdafx.h» if I don’t include it.

Also, for squareIntegers(22), I used this in my last program, and it worked fine. I have no idea what else could be the issue.

They are function prototypes.

Yes they are, but they don’t match your functions!
This prototype:

You’re telling the compiler about a different function. This one takes an integer and returns an integer.

This issue becomes apparent when you move your functions implementations below your main function:

(10): error C2660: ‘squareIntegers’ : function does not take 1 arguments
(11): error C2660: ‘squareDouble’ : function does not take 1 arguments
(12): error C2660: ‘squareFloat’ : function does not take 2 arguments

Because your prototypes should be:

Okay, thanks for that, but I still have this error: «fatal error LNK1169: one or more multiply defined symbols found.»

Does this mean in my squareFloat function, I need to make a struct, return the struct name? Will that get rid of this error?

Источник

Fatal error lnk1169 one or more multiply defined symbols found

Answered by:

Question

I’ve read other posts about this and usually it’s caused by accidently adding two or more copies of the same source code to the project.

I have three source code files and I can’t identify which symbol is ‘multiply defined’. This link error only occured when I started building the release version, it was fine on debug, so I have no idea when the problem started.

Here is the full error report:

—— Rebuild All started: Project: solver, Configuration: Release Win32 ——

Deleting intermediate and output files for project ‘solver’, configuration ‘Release|Win32’

.solver.cpp(240) : warning C4244: ‘=’ : conversion from ‘double’ to ‘float’, possible loss of data

.solver.cpp(269) : warning C4305: ‘=’ : truncation from ‘double’ to ‘float’

.solver.cpp(271) : warning C4244: ‘=’ : conversion from ‘double’ to ‘float’, possible loss of data

warning C4727: PCH named c:documents and settingsusermy documentsvisual studio 2005projectssolversolverreleasesolver.pch with same timestamp found in c:Documents and SettingsuserMy DocumentsVisual Studio 2005ProjectssolversolverReleasestdafx.obj and c:Documents and SettingsuserMy DocumentsVisual Studio 2005ProjectssolversolverReleasesolver.obj. Using first PCH.

stdafx.obj : error LNK2005: ___@@_PchSym_@00@UwlxfnvmghLzmwLhvggrmthUfhviUnbLwlxfnvmghUerhfzoLhgfwrlLCAAFUkilqvxghUhloeviUhloeviUivovzhvUhgwzucOlyq@ already defined in solver.obj

C:Documents and SettingsuserMy DocumentsVisual Studio 2005ProjectssolverReleasesolver.exe : fatal error LNK1169: one or more multiply defined symbols found

Build log was saved at «file://c:Documents and SettingsuserMy DocumentsVisual Studio 2005ProjectssolversolverReleaseBuildLog.htm»

solver — 2 error(s), 3 warning(s)

========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Источник

Fatal error lnk1169 one or more multiply defined symbols found

При компиляции происходят ошибки:
1 — error LNK2005: _assetType already defined in customer.obj
2 — fatal error LNK1169: one or more multiply defined symbols found
Погуглив я понял, что компилятор вставляет 2 раз вот это

но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз
Почему тогда происходит ошибка и как ее исправить?
Большое спасибо.

От: Caracrist https://1pwd.org/
Дата: 07.06.09 12:10
Оценка: -2
От: Caracrist https://1pwd.org/
Дата: 07.06.09 12:26
Оценка: +1

Здравствуйте, Caracrist, Вы писали:

C>this ?
C>
это я прогнал

От: andrey.desman
Дата: 07.06.09 12:45
Оценка:
От: Alexey F
Дата: 07.06.09 12:51
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>При компиляции происходят ошибки:
TA>1 — error LNK2005: _assetType already defined in customer.obj
TA>2 — fatal error LNK1169: one or more multiply defined symbols found
TA>Погуглив я понял, что компилятор вставляет 2 раз вот это
TA>

В дополнение к данным выше ответам:

Так тоже будет работать (подразумевается внутреннее связывание).

TA>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз
Верно. По одному разу в каждый файл, который подключил customer.h.

P.S. Если нет желания делать массив константным или внутренним для каждой единицы трансляции, то только так:
в заголовке его объявляем с extern, а определяем в отдельном .c/.cpp файле

От: TheAteist
Дата: 07.06.09 20:01
Оценка:
От: TheAteist
Дата: 07.06.09 20:02
Оценка:
От: Kirikaza kirikaza.ru
Дата: 07.06.09 20:35
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?
TA>2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?

#include «x.h» лучше рассматривать как «вставить в этом месте содержимое файла x.h».

Пусть есть файл x.h:

Если файл x.h вставлен дважды в некий C-файл

то получается вот так:

При этом первый #ifndef сработает, т.к. X_H ещё не определена, и определит X_H. А второй #ifndef не сработает, т.к. X_H уже определена.

Когда происходит компиляция, препроцессор берёт C-файл выполняет вот эту подстановку и оставляет код внутри первого #if и выкидывает внутри второго. Затем полученный код отдаётся компилятору, который компилирует и получает объектный файл. Затем берётся второй C-файл и для него независимо от первого C-файла процедура повторяется заново (т.е. в самом начале обработки препроцессором второго C-файла X_H никем не была определена). Когда все объектные файлы получены, они все линкуются (связываются) в один.

В твоём случае H-файл включается по разу в каждый подключающий его C-файл. Объектные файлы получаются с копиями того массива, но компилятор при создании каждого из них об этом не знает. А вот линковщик (linker) видит две вещи с одним именем в одной глобальной области и пугается, т.к. для обеих из них есть определение.

Т.е. H-файлы сами по себе непосредственно не обрабатываются. Всё исходит от C-файлов. Ну а что делать — тебе уже сказали.

P.S.: На самом деле компиляторы данный процесс обычно оптимизируют, но поведение такое сохраняют.

От: Alexey F
Дата: 07.06.09 20:46
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?

include-guard (те самые #ifndef/#define/#endif) нужны для других целей. А, именно, для предотвращения включения текста включаемого файла дважды в одну и ту же единицу трансляции. Такое может произойти, например, когда файл X.h включает файл Y.h, а потом включает файл Z.h, который, в свою очередь, снова подключает Y.h. Без include-guard’ов получили бы множество ошибок переопределения.

TA>2)И если подключается по одной копии в каждый сишник, так разве #ifndef не был придуман, чтоб сэкономить место на диске и подключать только один раз?
Сэкономить место на диске? Нет, скорее сэкономить время и нервы программиста, избавляя его от перебивания одинаковых строк из файла в файл
В Вашем случае решение ситуации в смене связывания объявляемому массиву. Как это сделать — уже описали выше (static, const, extern).

P.S. Ещё безымянные namespace могут решить проблему, но по мне лучше уж const или вынос определения в отдельную единицу трансляции.

От: TheAteist
Дата: 07.06.09 21:19
Оценка:
От: TheAteist
Дата: 07.06.09 21:21
Оценка:
От: Alexey F
Дата: 07.06.09 22:36
Оценка:

Здравствуйте, TheAteist, Вы писали:

[offtop]
Зачем дублируете ответы? И оверквотинг лишний.
[/offtop]

TA>Это я понял. Я не понял почему только на массив все «крики», а не, скажем на «typedef enum assetAction;» который у меня определяется под массивом. Или на определений функций, которые и они находятся в том же customer.h и все в #ifndef.

Здесь разные вещи. С помощью typedef enum Вы определяете тип.
А

определяет переменную, которая уже имеет по-умолчанию внешнее связывание, т.е. учавствует при линковке. Соответственно, получаются две переменные с одним и тем же именем, определённые в двух разных файлах трансляции. Какую прикажете выбирать линкеру?
Иллюстрация более наглядного случая (чтобы было понятно, почему линковщик не имеет право плюнуть на это и выбрать одно из определений):

P.S. Даже если тела Ваших массивов одинаковы, для линкера — это две переменных с одним и тем же именем.

От: LaptevVV
Дата: 08.06.09 07:29
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>При компиляции происходят ошибки:
TA>1 — error LNK2005: _assetType already defined in customer.obj
TA>2 — fatal error LNK1169: one or more multiply defined symbols found
TA>Погуглив я понял, что компилятор вставляет 2 раз вот это
TA>
TA>но я же добавил в customer.h #ifndef, значит «const char* assetType» должен добавлсят только 1 раз
TA>Почему тогда происходит ошибка и как ее исправить?
TA>Большое спасибо.

Я обычно делаю так:
1. Все переменные и константы, которые мне нужны в нескольких единицах трансляции, выношу в отдельный файл вроде variable.cpp
2. Пишу variable.h, в котором делаю ОБЪЯВЛЕНИЯ

3. К единицам трансляции подключаю variable.h

От: рыбак
Дата: 08.06.09 10:49
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>1)Так если в любом случае подключается по одной копии в каждый сишник, который подключил customer.h, так зачем тогда нужен #ifndef? Или что-то не так понял?

#ifndef (или #pragma once) защищает от двойного включения заголовка (.h) в одну единицу компиляции (.cpp). То есть для удачной компиляции.
У тебя же ошибка линковки. Это когда в двух разных единицах компиляции (.cpp) получился одинаковый символ.

От: Аноним
Дата: 08.06.09 11:15
Оценка:

Здравствуйте, LaptevVV, Вы писали:

LVV>Я обычно делаю так:
LVV>1. Все переменные и константы, которые мне нужны в нескольких единицах трансляции, выношу в отдельный файл вроде variable.cpp

А все классы, которые нужны в нескольких единицах трансляции выносишь в файл вроде class.cpp? Одно непонятно, откуда при таком подходе появляется больше одной единицы трансляции.

От: Юрий Жмеренецкий ICQ 380412032
Дата: 08.06.09 11:40
Оценка:

Здравствуйте, TheAteist, Вы писали:

TA>Я не понял почему только на массив все «крики», а не, скажем на «typedef enum assetAction;» который у меня определяется под массивом.

Это enumerator-definition, а для таких (и некоторых других) определений есть список условий, при соблюдении которых уникальность (определения в пределах программы) не является обязательной (3.2/5).

TA>Или на определений функций, которые и они находятся в том же customer.h и все в #ifndef.
В приведенном выше коде в файле ‘customer.h’ находится объявление функции (func), а не определение.

PS: Поищи по «One definition rule», здесь это неоднократно обсуждалось.

От: TheAteist
Дата: 08.06.09 17:28
Оценка:

Здравствуйте, Alexey F, Вы писали:

AF>P.S. Даже если тела Ваших массивов одинаковы, для линкера — это две переменных с одним и тем же именем.
Кажется я понял
Значит премерно вот так получается, да?

От: LaptevVV
Дата: 09.06.09 05:18
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, LaptevVV, Вы писали:

LVV>>Я обычно делаю так:
LVV>>1. Все переменные и константы, которые мне нужны в нескольких единицах трансляции, выношу в отдельный файл вроде variable.cpp

А>А все классы, которые нужны в нескольких единицах трансляции выносишь в файл вроде class.cpp? Одно непонятно, откуда при таком подходе появляется больше одной единицы трансляции.
Зачем-же? Речь идет не о классах, а об общих переменных. Если они требуются, конечно.

Каждый класс — это class.h и class.cpp
Можно в class.h собрать несколько классов, но лучше разделить.

От: Аноним
Дата: 09.06.09 11:23
Оценка:

Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, Аноним, Вы писали:

А>>Здравствуйте, LaptevVV, Вы писали:

LVV>Зачем-же? Речь идет не о классах, а об общих переменных. Если они требуются, конечно.

LVV>Каждый класс — это class.h и class.cpp
LVV>Можно в class.h собрать несколько классов, но лучше разделить.

А почему лучше их разделить и почему нельзя эти рассуждения применить к общим переменным?

Источник

Я тренировался использовать объектно-ориентированное программирование в C ++, но я продолжаю получать эту ошибку:

1>main.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj
1>main.obj : error LNK2005: "int HEIGHT" (?HEIGHT@@3HA) already defined in GameObject.obj
1>Spaceship.obj : error LNK2005: "int WIDTH" (?WIDTH@@3HA) already defined in GameObject.obj
1>Spaceship.obj : error LNK2005: "int HEIGHT" (?HEIGHT@@3HA) already defined in GameObject.obj
1>C:Usersteddocumentsvisual studio 2010ProjectsfullSpaceDebugfullSpace.exe : fatal error LNK1169: one or more multiply defined symbols found

Однако, мне кажется, что весь код написан правильно, и эти два целых числа упоминаются только в глобальном заголовке, и все объекты, похоже, наследуются правильно. Однако, как я только что сказал, я новичок в ООП, поэтому мне действительно нужно мнение: Стоит также упомянуть, что я использую allegro 5 для создания бокового шутера.

Это код:

(главный):

#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_font.h>
#include <allegro5allegro_ttf.h>
#include <allegro5allegro_audio.h>
#include <allegro5allegro_acodec.h>

#include <list>#include "GameObject.h"#include "Spaceship.h"#include "Globals.h"//controls

bool keys[] = {false, false, false, false, false};
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};

//globals
Spaceship *ship;

std::list <GameObject *> objects;
std::list <GameObject *>::iterator iter;
std::list <GameObject *>::iterator iter2;//prototypes//main function
int main(int argc, char **argv)
{
//shell variables
bool done = false;
bool render = false;

float gameTime = 0;
int frames = 0;
int gameFPS = 0;

//project variables

ship = new Spaceship();ALLEGRO_BITMAP *shipImage = NULL;
ALLEGRO_BITMAP *cometImage= NULL;
ALLEGRO_BITMAP *explImage = NULL;
ALLEGRO_BITMAP *bgImage = NULL;
ALLEGRO_BITMAP *mgImage = NULL;
ALLEGRO_BITMAP *plImage = NULL;
ALLEGRO_BITMAP *mgImage2 = NULL;
ALLEGRO_BITMAP *fgImage = NULL;
ALLEGRO_BITMAP *titleImage= NULL;
ALLEGRO_BITMAP *lostImage = NULL;//allegro variables
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer;
ALLEGRO_FONT *font18;//initiate variables
if(!al_init())
return -1;

display = al_create_display(WIDTH, HEIGHT);
if(!display)
return -1;

//addon installation

al_install_keyboard();
al_init_image_addon();
al_init_font_addon();
al_init_ttf_addon();
al_init_primitives_addon();
al_install_audio();
al_init_acodec_addon();

//project init

font18 = al_load_font("arial.ttf", 18, 0);
al_reserve_samples(15);bgImage = al_load_bitmap("layer1.png");
mgImage = al_load_bitmap("layer2.png");
plImage = al_load_bitmap("starMG.png");
mgImage2 = al_load_bitmap("layer3.png");
fgImage = al_load_bitmap("layer4.png");shipImage = al_load_bitmap("spaceship.png");
al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));cometImage = al_load_bitmap("asteroid-1-96.png");
explImage = al_load_bitmap("explosion_3_40_128.png");

titleImage = al_load_bitmap("Shooter_Title.png");
lostImage = al_load_bitmap("Shooter_Lose.png");//object init
ship->init(shipImage);//iter list
objects.push_back(ship);srand(time(NULL));

//timer init and startup

event_queue = al_create_event_queue();
timer = al_create_timer(1.0 / 60);

al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_register_event_source(event_queue, al_get_keyboard_event_source());

al_start_timer(timer);
gameTime = al_current_time();

while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);

//input
if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = true;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = true;
break;
case ALLEGRO_KEY_SPACE:
keys[SPACE] = true;
break;}
} else if(ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_UP:
keys[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = false;
break;
case ALLEGRO_KEY_SPACE:
keys[SPACE] = false;
break;
}
}else if (ev.type == ALLEGRO_EVENT_TIMER)
{
render = true;

//fps
frames++;
if(al_current_time() - gameTime >= 1)
{
gameTime = al_current_time();
gameFPS = frames;
frames = 0;
}

//shipUpdate

if(keys[UP])
ship ->moveUp();
else if(keys[DOWN])
ship ->moveDown();
else
ship->resetAnim(1);

if(keys[LEFT])
ship ->moveLeft();
else if(keys[RIGHT])
ship -> moveRight();
else
ship ->resetAnim(0);

}
//render

if(render && al_is_event_queue_empty(event_queue))
{
render = false;

//begin render
for(iter = objects.begin(); iter != objects.end(); ++iter)
(*iter)->render();//Flip Buffers
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
}
}

//destroy objects//visual objects
al_destroy_bitmap(cometImage);
for(iter = objects.begin(); iter != objects.end(); ++iter)
(*iter)->destroy(shipImage);
iter = objects.erase(iter);

al_destroy_bitmap(explImage);
al_destroy_bitmap(bgImage);
al_destroy_bitmap(mgImage);
al_destroy_bitmap(fgImage);
al_destroy_bitmap(titleImage);
al_destroy_bitmap(lostImage);

//audio objects
/*
al_destroy_sample(shot);
al_destroy_sample(boom);
al_destroy_sample(song);
al_destroy_sample_instance(songInstance);
*///shell objects
al_destroy_font(font18);
al_destroy_timer(timer);
al_destroy_event_queue(event_queue);
al_destroy_display(display);

return 0;
}

(Globals.h):

#pragma once

int WIDTH = 1024;
int HEIGHT = 800;

enum ID{PLAYER, ENEMY, BULLET, BORDER, MISC};
enum STATES{TITLE, PLAYING, LOST};

(GameObject.h):

#pragma once#include "Globals.h"#include <iostream>

#include <allegro5/allegro5.h>

#include <allegro5/allegro_primitives.h>class GameObject
{
private:
int ID;
bool alive;
bool collidable;

protected:
float x;
float y;

float velX;
float velY;

int dirX;
int dirY;

int boundX;
int boundY;

int maxFrame;
int curFrame;
int frameCount;
int frameDelay;
int frameWidth;
int frameHeight;
int animationColumns;
int animationDirection;

ALLEGRO_BITMAP *image;

public:
GameObject();
void virtual destroy(ALLEGRO_BITMAP *image);

void init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY);
void virtual update();
void virtual render();

float getX() {return x;}
float getY() {return y;}

void setX(float x) {GameObject::x = x;}
void setY(float y) {GameObject::y = y;}

int getBoundX() {return boundX;}
int getBoundY() {return boundY;}

int getID() {return ID;}
void setID(int ID) {GameObject::ID = ID;}

bool getAlive() {return alive;}
void setAlive(bool alive) {GameObject::alive = alive;}

bool getCollidable() {return collidable;}
void setCollidable(bool collidable) {GameObject::collidable = collidable;}

bool checkCollisions(GameObject *otherObject);
void virtual collided(int objectID);
bool collidableCheck();
};

(GameObject.cpp):

#include "GameObject.h"
GameObject::GameObject()
{
x = 0;
y = 0;

velX = 0;
velY = 0;

dirX = 0;
dirY = 0;

boundX = 0;
boundY = 0;

maxFrame = 0;
curFrame = 0;
frameCount = 0;
frameDelay = 0;
frameWidth = 0;
frameHeight = 0;
animationColumns = 0;
animationDirection = 0;

image = NULL;

alive = true;
collidable = true;

}

void GameObject::destroy(ALLEGRO_BITMAP *image)
{
if(image != NULL)
al_destroy_bitmap(image);

}
void GameObject::init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY)
{
GameObject::x = x;
GameObject::y = y;

GameObject::velX = velX;
GameObject::velY = velY;

GameObject::dirX = dirX;
GameObject::dirY = dirY;

GameObject::boundX = boundX;
GameObject::boundY = boundY;

}

void GameObject::update()
{
x += velX*dirX;
y += velY*dirY;
}

void GameObject::render()
{

}

bool GameObject::checkCollisions(GameObject *otherObject)
{
float oX = otherObject->getX();
float oY = otherObject->getY();

int obX = otherObject->getBoundX();
int obY = otherObject->getBoundY();

if(x + boundX > oX - obX &&
x - boundX < oX + obX &&
y + boundY > oY - obY &&
y - boundY < oY + obY
)
return true;
else
return false;
}

void GameObject::collided(int objectID)
{

}
bool GameObject::collidableCheck()
{
return alive && collidable;
}

(SpaceShip.h):

#pragma once

#include "GameObject.h"
class Spaceship : public GameObject
{
private :
int lives;
int score;
int animationRow;

public :
Spaceship();

void destroy(ALLEGRO_BITMAP *image);

void init(ALLEGRO_BITMAP *image = NULL);

void update();
void render();

void moveUp();
void moveDown();
void moveLeft();
void moveRight();

void resetAnim(int pos);

int getLives(){return lives;}

int getScore() {return score;}

void looseLife() {lives--;}
void addPoint() {score++;}

void collide(int objectID);};

(SpaceShip.cpp):

#include "Spaceship.h"
Spaceship::Spaceship()
{}

void Spaceship::destroy(ALLEGRO_BITMAP *image)
{
GameObject::destroy(image);
}
void Spaceship::init(ALLEGRO_BITMAP *image)
{
GameObject::init(20, 200, 6, 6, 0, 0, 10, 12);

setID(PLAYER);
setAlive(true);

lives = 3;
score = 0;

maxFrame = 3;
curFrame = 0;
frameWidth = 46;
frameHeight = 41;
animationColumns = 3;
animationDirection = 1;

animationRow = 1;

if(image != NULL)
{
Spaceship::image = image;
}
}

void Spaceship::update()
{
GameObject::update();
if(x < 0)
x=0;
else if ( x > WIDTH)
x = WIDTH;
if(y < 0)
y = 0;
else if (y > HEIGHT)
y = HEIGHT;
}
void Spaceship::render()
{
GameObject::render();

int fx = (curFrame % animationColumns) *frameWidth;
int fy = animationRow *frameHeight;

al_draw_bitmap_region(image, fx, fy, frameWidth, frameHeight,
x - frameWidth /2, y - frameHeight /2, 0);

}

void Spaceship::moveUp()
{
animationRow = 0;
dirY = -1;

}
void Spaceship::moveDown()
{
animationRow = 2;
dirY = 1;
}
void Spaceship::moveLeft()
{
curFrame = 2;
dirX = -1;
}
void Spaceship::moveRight()
{
curFrame = 1;
dirX = 1;
}

void Spaceship::resetAnim(int pos)
{
if(pos == 1)
{
animationRow = 1;
dirY = 0;
}
else
{
curFrame = 0;
dirX = 0;
}
}

void Spaceship::collide(int objectID)
{
if(objectID == ENEMY)
lives--;

}

17

Решение

Два int переменные определенный в заголовочном файле. Это означает, что каждый исходный файл, который включает заголовок, будет содержать их определение (включение заголовка является чисто текстовым). Конечно, приводит к множественным ошибкам определения.

У вас есть несколько вариантов, чтобы это исправить.

  1. Сделать переменные static (static int WIDTH = 1024;). Они будут по-прежнему существовать в каждом исходном файле, но их определения не будут видны за пределами исходного файла.

  2. Превратите их определения в декларации, используя extern (extern int WIDTH;) и положить определение в один исходный файл: int WIDTH = 1024;,

  3. Вероятно, лучший вариант: сделать переменные const (const int WIDTH = 1024;). Это делает их static неявно, а также позволяет использовать их в качестве констант времени компиляции, что позволяет компилятору использовать их значение напрямую, а не выдавать код для чтения его из переменной и т. д.

48

Другие решения

Вы не можете помещать определения переменных в файлы заголовков, так как они будут частью всего исходного файла, в который вы включаете заголовок.

#pragma once просто для защиты от нескольких включений в одном исходном файле, а не от нескольких включений в нескольких исходных файлах.

Вы могли бы объявлять переменные как extern в заголовочном файле, а затем определять их в одном исходном файле. Или же вы можете объявить переменные как const в заголовочном файле, и компилятор и компоновщик будут управлять им.

5

const int WIDTH = 1024;
const int HEIGHT = 800;

2

Write your question here. Hi, it is me again. I am getting this error and cannot figure out what I am doing wrong. It is in visual studios 2013 again BTW.

[#include «stdafx.h» // Precompiled header
#include «iostream» // Input and output stream
using namespace std; // Meaning you don’t have to put std:: before cout <<;.
int squareIntegers(); // Function Prototype
double squareDouble();
float squareFloat();

int squareIntegers(int x) { //Function
int solution; //Declaring the variable solution, which is an integer data type.
solution = x * x; // Squaring x.
return solution; //Returns solution

}

double squareDouble(double d) {
double answer;
answer = d * d;
return answer;
}

float squareFloat(float x, float y) {
float answer1;
float answer2;
answer1 = x * x;
answer2 = y * y;
return 0;
}

int main() //Main Function
{
cout << squareIntegers(22) << endl;
cout << squareDouble(12) << endl;
cout << squareFloat(132, 150) << endl; //Function call and display with value 22 (so x = 22)
system(«pause»); // Helps with displaying the output of a program.
return 0; // Returns a value.
}
code]
Put the code you need help with here.
[/code]

Last edited on

can you use code tags please?

you need to read this:
http://www.cplusplus.com/doc/tutorial/functions/

for example, you prototype:
int squareIntegers();

but you call it like this:
squareIntegers(22)

you also do not need prototype declarations if you’re implementing them before you call them.
i.e. delete these:

1
2
3
4

int squareIntegers(); // Function Prototype
double squareDouble();
float squareFloat();

Last edited on

I’m trying to but it keeps displaying like that.

besides the functions issue there is also this:

1
2
3
4
5
6
7
float squareFloat(float x, float y) {
	float answer1;
	float answer2;
	answer1 = x * x;
	answer2 = y * y;
	return 0;
}

why are you doing calculations and then return zero?

edit:
you also do not need this either:
#include "stdafx.h"

Last edited on

I did it because I cannot return both answer1 and answer2 twice. What is the function issue?

please read my first post. basically these lines:

1
2
3
4
int squareIntegers(); // Function Prototype
double squareDouble();
float squareFloat();

are wrong, and not even needed.

I did it because I cannot return both answer1 and answer2 twice.

You need to read that link i pasted on functions.

Okay

So, I read it but and why are
[int squareIntegers(); // Function Prototype
double squareDouble();
float squareFloat();], wrong. They are function prototypes.

Also, I get an error saying to include «stdafx.h» if I don’t include it.

Also, for squareIntegers(22), I used this in my last program, and it worked fine. I have no idea what else could be the issue.

Also, how do you use the tags. I click on <>, then this comes up: , but where in the brackets do I paste my code? I pasted in the brackets and it doesn’t work. Is there a specific location in the brackets where I should paste my code?

They are function prototypes.

Yes they are, but they don’t match your functions!
This prototype:

Tells your compiler you’re going to supply a method that takes NO parameters and returns an integer. However when you get to your code:

 
int squareIntegers(int x) 

You’re telling the compiler about a different function. This one takes an integer and returns an integer.

This issue becomes apparent when you move your functions implementations below your main function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "iostream" // Input and output stream
using namespace std; // Meaning you don't have to put std:: before cout <<;.

int squareIntegers(); // Function Prototype
double squareDouble();
float squareFloat();

int main() //Main Function
{
	cout << squareIntegers(22) << endl;
	cout << squareDouble(12) << endl;
	cout << squareFloat(132, 150) << endl;	//Function call and display with value 22 (so x = 22)
	system("pause");	// Helps with displaying the output of a program.
	return 0;	// Returns a value.
}

int squareIntegers(int x) {	//Function
	int solution;	//Declaring the variable solution, which is an integer data type. 
	solution = x * x;	// Squaring x.
	return solution;	//Returns solution

}

double squareDouble(double d) {
	double answer;
	answer = d * d;
	return answer;
}

float squareFloat(float x, float y) {
	float answer1;
	float answer2;
	answer1 = x * x;
	answer2 = y * y;
	return 0;
}

errors:

(10): error C2660: ‘squareIntegers’ : function does not take 1 arguments
(11): error C2660: ‘squareDouble’ : function does not take 1 arguments
(12): error C2660: ‘squareFloat’ : function does not take 2 arguments

Because your prototypes should be:

1
2
3
4

int squareIntegers(int); // Function Prototype
double squareDouble(double);
float squareFloat(float, float);

Last edited on

Okay, thanks for that, but I still have this error: «fatal error LNK1169: one or more multiply defined symbols found.»

Does this mean in my squareFloat function, I need to make a struct, return the struct name? Will that get rid of this error?

I don’t don’t get any errors when I compile your code.

Hmmmm…. Stange. I even copy and pasted the code you had and I am still getting the error:
«fatal error LNK1169: one or more multiply defined symbols found.»

Also, I still have to add #include «stdafx.h» or else I will get an error saying I am missing that.

I’m using visual studios 2013.

I got it running!
But I have two problems.

1) It says I have to return something in the squareFloat function, but whatever I return (even 0), it will show in the output display box? What can I return that will make nothing display?

2) How do I create spaces between numbers? For example, instead of 1213, how would I make this 12 13?

Okay, I figured out the spacing part, but I still need help on the return part.

Can someone please help? This is all I need and I will be done.

what is the function meant to do? «squareFloat» implies to me that you are squaring a float? i.e. it takes in one float and returns a float.

Also, I still have to add #include «stdafx.h» or else I will get an error saying I am missing that.

what kind of project have you created?? You don’t need this at all.

Last edited on

Topic archived. No new replies allowed.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • One or more devices has experienced an error resulting in data corruption
  • One drive код ошибки 0х8004de40
  • On july 7 the roblox application will require directx 10 как исправить
  • On host zabbix server failed first network error wait for 15 seconds
  • On error миф excel

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии