C++ 主要语法错误?(12 个重复的符号用于建筑x86_64)[复制]

C++ Major syntax error? (12 Duplicate Symbols for architecture x86_64) [duplicate]

提问人:mjsyts 提问时间:9/22/2022 最后编辑:mjsyts 更新时间:9/22/2022 访问量:152

问:

为我的无知道歉。我对另一种语言的 C++ 比较陌生。我正在制作一个程序来对扑克牌进行排名,但我遇到了一个我不明白的错误,但我假设这是一个主要的语法错误。请友善,我正在努力学习。这不会在 Xcode 中构建。当我尝试时,我收到以下错误消息:

12 建筑x86_64的重复符号

我真的对这个错误感到困惑。这是我的代码:

扑克.hpp

#ifndef poker_hpp
#define poker_hpp

#include <stdio.h>
#include <iostream>
#include <array>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

const size_t HAND_ARRAY_SIZE = 5;
const size_t CARD_ARRAY_SIZE = 2; //just in case, might not use it

typedef array<string, HAND_ARRAY_SIZE> hand_t; //typedef for poker hands

typedef array<string, CARD_ARRAY_SIZE> card_t; //just in case, might not use it

const size_t SUIT_ARRAY_SIZE = 4;
static array<string, SUIT_ARRAY_SIZE> suits =
{"C", "D", "H", "S"};

const size_t VALUE_ARRAY_SIZE = 13;
static array<string, VALUE_ARRAY_SIZE> ranks_ace_high =
{"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
static array<string, VALUE_ARRAY_SIZE> ranks_ace_low =
{"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"};

const size_t HAND_RANK_ARRAY_SIZE = 10;
//EDIT: added static
static array<string, HAND_RANK_ARRAY_SIZE> handRanks =
{
    "high card",
    "pair",
    "two pair",
    "three of a kind",
    "straight"
    "flush",
    "full house",
    "four of a kind",
    "straight flush",
    "royal flush"
};

class Hand {
private:
    hand_t cards;
    string type();
    float value();
    bool acesLow();
public:
    Hand(hand_t cards);
};

#endif /* poker_hpp */

test_hands.cpp

#include "poker.hpp"

hand_t test0 {"TC", "9C", "8C", "7C", "6C"};
hand_t test1 {"8H", "7H", "6H", "5H", "4H"};
hand_t test2 {"8H", "7H", "6H", "5H", "4H"};
hand_t test3 {"6S", "5S", "4S", "3S", "2S"};
hand_t test4 {"7D", "6D", "5D", "4D", "3D"};
hand_t test5 {"7S", "6S", "5S", "4S", "3S"};
hand_t test6 {"KS", "KH", "KC", "KD", "3H"};
hand_t test7 {"7H", "7D", "7S", "7C", "QH"};
hand_t test8 {"7H", "7D", "7S", "7C", "QH"};

手.cpp

#include "poker.hpp"

Hand::Hand(hand_t cards){
    this->cards = cards;
}

main.cpp

#include "poker.hpp"
#include "test_hands.cpp"

int main() {
    Hand hand(test0);
};
C++ 数组 xcode 语法错误

评论

1赞 user4581301 9/22/2022
在标头中定义变量是很棘手的。包含标头的每个文件都将获得自己的副本,从而导致多个定义。大多数标头定义的变量都是这样,它们就不会渗入其他翻译单元,但看起来它被遗漏了。statichandRanks
0赞 mjsyts 9/22/2022
谢谢,这是问题的一部分。不过,它只是从 12 个增加到 9 个
0赞 user4581301 9/22/2022
您不得包含 cpp 文件。编译并链接它。智能构建工具将看到 cpp 扩展并自动构建它,所以 kabong!现在,您在 cpp 文件的编译版本内的 cpp 文件中定义了各种函数和变量,并且包含 cpp 文件的所有文件都包含 cpp 文件的副本,因此编译器有效地使用包含的 cpp 文件再次编译包含的 cpp,并且该文件的输出再次包含所有定义。链接器并不在乎它们是否都是一样的,它只是举起双臂并吐出一个错误。
0赞 mjsyts 9/22/2022
完善!这个我还不知道/理解。这是我第一次涉足 C++。感谢您的善意回答!
0赞 user4581301 9/22/2022
这里有一些关于如何在 C++ 中构建和组合所有部分的好读物。应该可以帮助您在未来摆脱这种麻烦:stackoverflow.com/questions/6264249/......

答:

0赞 user4581301 9/22/2022 #1

有两个问题。在包含文件时,include 指令将在预处理阶段有效地替换为命名文件的内容。这将生成一个大文件,其中包含源文件的内容以及所有包含的标头以及编译的其他标头包含的所有标头。

这意味着在头文件中定义某些内容时必须小心:包括头文件在内的每个人都将拥有自己的定义副本,这将违反一个定义规则,除非您采取额外步骤将定义锁定在正在编译的翻译单元中(链接或匿名命名空间)或告诉编译器所有副本都是相同的(函数)。staticinline

在 poker.hpp 中,

array<string, HAND_RANK_ARRAY_SIZE> handRanks = { ... };

没有或绑定在匿名命名空间中,因此每个包含的源文件都定义了一个对象,当链接器将所有内容放在一起时,它找到了所有对象并拒绝继续。statichandRankshandRanks

第二个问题是主要的.cpp包括test_hands.cpp。这复制了 test_hands.cpp 中的所有内容.cpp。IDE 将 test_hands.cpp 和 main.cpp发送到编译器,每个源代码的输出都包含在 test_hands.cpp 中定义的所有内容,从而导致更多多个定义。不要包含 cpp 文件。而是编译和链接它们。

test_hands.cpp中需要向其他文件公开或由其他文件共享的任何内容都应在其他源文件包含的标头中声明。Extern 将在这里提供帮助。也就是说,在本例中,只需将测试数据构建到 main.cpp 中即可。没有充分的理由将测试数据与测试驱动程序分开,除非它很大或很复杂,并且你希望尽可能少地编译它。

战术说明:

在进入构造函数的主体之前,所有类成员和基类都已完全初始化。这意味着在

Hand::Hand(hand_t cards){
    this->cards = cards;
}

member 默认初始化(这反过来又默认初始化 s),然后成员被参数覆盖,使初始化浪费了精力。一个好的优化编译器可能会发现这种浪费并消除它,但相反,你可以利用成员初始值设定项列表,通过准确说明你想要的行为,使编译器的工作更轻松。cardsHAND_ARRAY_SIZEstringcardscards

Hand::Hand(hand_t cards): cards(cards){

}

成员现在使用参数 进行复制初始化。请注意,我们还可以毫不含糊地重复使用该名称。cardscardscards

当您的数据结构具有编译器无法轻易消除的昂贵默认初始化时,这一点非常重要,而当基类或成员变量无法默认初始化时,这一点至关重要。