0

目前,我有 9 种不同的功能,而其中只有几个实际上可以做任何事情——商店、主屏幕和选择屏幕。我希望我的货币在选择屏幕中全球化并且做#inculde“shop.cpp”不起作用,它只是给我一个错误,说shop.obj已经定义:商店的代码有点长,所以我将只发布前几行,直到我希望全球化变量实际使用的地方。

#include <iostream>
#include "gp.cpp"
using namespace std;

double smallNet = 0, bronzeAxe = 0;
int availableGP;
int skillselection();

int shop()
{
    int itemPurchase = 0;
    double shopCont = 0;

    cout << " \n\n\n\nWelcome to the General Store.";
    cout << "\n We sell many supplies, you";
    cout << "\n will need throughout your";
    cout << "\n adventure! Please take a look!";

    cin.get();
    cin.get();

    while (shopCont != 2)
    {
        system("cls");

        cout << "________________________________" << endl;
        cout << "|_______Item_______|___Cost____|" << endl;
        cout << "| Small Net     (1)| 10gp      |" << endl;
        cout << "| Bronze Axe    (2)| 100gp     |" << endl;
        cout << "|__________________|___________|" << endl;
        cout << "Gold: " << availableGP << endl;

下一段代码来自 gp.cpp

#include <iostream>
using namespace std;

int gp()
{
    int availableGP = 112;
    return availableGP;
}

我知道我说过我希望从选择屏幕调用它 - 但是代码不会进入代码框:\所以这看起来很糟糕。正如我在开始时所说,我的代码非常初级,所以不要让我放入 std::iostream=array::index 或类似的东西,哈哈

我尝试编译时收到的错误消息: shop.obj : error LNK2005: "int __cdecl gp(void)" (?gp@@YAHXZ) already defined in gp.obj

“cdecl gp(void)”到底是什么意思?我的程序中没有任何空白。而且我也不知道 ?gp@@YAHXZ 是什么意思 :\ 我觉得我需要重修我的 C++ 课,因为老师只让我们编程了 3 次,而且它在第 12 周进行......讲座讲座讲课……有点​​烦

抱歉,如果这是一个愚蠢的重复问题,但我不知道每个人使用的任何特殊东西是什么,比如 .h 文件或 conio 或类似的东西:\ 我只需要制作在 main 中有效的东西,所以......这是一个巨大的进步......因为我很无聊,想弄清楚如果我这样做会发生什么......

谢谢,如果有人能给我一个我正在寻找的虚拟答案:)

4

2 回答 2

0

除了最好避免使用全局变量(最好考虑单例模式或类似的东西)这一事实之外,您的问题是您要编译 gp() 函数两次(编译 gp.cpp 时编译一次,编译 gp.cpp 时编译一次)包含在另一个文件中)。这就是那个错误的意思。要解决它,您可以制作一个头文件“gp.h”,例如:

#ifndef __GP_H__
#define __GP_H__

int gp();

#endif

然后在两个 .cpp 文件中使用

#include "gp.h"

(#ifndef 等只是为了避免头文件在同一个文件中包含两次)。

有了这个,你声明了这个函数,而不是“实现”它,所以编译器只会生成一次二进制代码。

于 2013-11-11T08:11:08.153 回答
0

在 C 和 C++ 中,代码通常分为头文件实现文件。头文件通常具有扩展名.h(或.hh.hppC++),实现文件具有扩展名,如.c,.cc.cpp.

实现文件是实际传递给编译器的东西。另一方面,头文件#include进入实现文件。#include告诉编译器(技术上是预处理器)将头文件复制并粘贴到实现中。一个特定的头文件可能会包含在许多实现中,并且头文件可以在必要时包含其他头文件。

通常,您将函数声明放入头文件,将函数定义放入实现文件。声明如下所示:

int multiply(int a, int b);

也就是说,它没有主体[1]。另一方面,定义在花括号中具有函数体,如下所示:

int multiply(int a, int b)
{
    return a * b;
}

只要所有声明都相同,您可以随意声明一个函数。在 C++(以及较新版本的 C)中,您必须在调用函数之前声明它。但是,重要的是,您只能提供一个定义——这就是所谓的One Definition Rule,这就是导致问题的原因。

您需要做的是将 的声明放入int gp()头文件(例如,称为 ,gp.hpp并且#include在定义shop().

就目前而言,编译器首先gp.cppint gp(). 然后它复制并粘贴gp.cpp到您的另一个文件中,并尝试创建第二段代码,也称为int gp(). 当它试图将它们组合成一个可执行文件时,它会看到它有两个具有相同名称的东西(技术上称为symbols),并且您会看到您看到的链接器错误。

(稍后,您可能会发现您想使用inline关键字将定义放入头文件中,但目前最好将您的代码分开。)

[1]:对于纯粹主义者:是的,我知道,定义也是声明 :-)

于 2013-11-11T08:15:54.840 回答