Xcode 错误:“架构 x86_64 的 2 个重复符号”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20184582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:20:52  来源:igfitidea点击:

Xcode error: "2 duplicate symbols for architecture x86_64"

c++xcode

提问by user3029918

I keep getting this error when I try to compile and have no idea why

我尝试编译时不断收到此错误,但不知道为什么

Ld /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Products/Debug/BATTLESHIP normal x86_64
    cd /Users/Itunes/Desktop/Programs/CMPSC122/BATTLESHIP
    setenv MACOSX_DEPLOYMENT_TARGET 10.7
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Products/Debug -F/Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Products/Debug -filelist /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Intermediates/BATTLESHIP.build/Debug/BATTLESHIP.build/Objects-normal/x86_64/BATTLESHIP.LinkFileList -mmacosx-version-min=10.7 -stdlib=libc++ -o /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Products/Debug/BATTLESHIP

duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK5Point in:
    /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Intermediates/BATTLESHIP.build/Debug/BATTLESHIP.build/Objects-normal/x86_64/main.o
    /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Intermediates/BATTLESHIP.build/Debug/BATTLESHIP.build/Objects-normal/x86_64/Board.o
duplicate symbol __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK5Point in:
    /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Intermediates/BATTLESHIP.build/Debug/BATTLESHIP.build/Objects-normal/x86_64/main.o
    /Users/Itunes/Library/Developer/Xcode/DerivedData/BATTLESHIP-gefqfgwzntvzlvfyyxoqzmmanjlb/Build/Intermediates/BATTLESHIP.build/Debug/BATTLESHIP.build/Objects-normal/x86_64/Ship.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

My headers and .cpp files are

我的头文件和 .cpp 文件是

Board.h
// Board.h - Board class declaration

#pragma once

#include "Point.h"
using namespace std;


#define HIT 'X'
#define SHIP 'S'
#define MISS 'O'
#define WATER '~'

class Board
{
public:
    // Constructor
    Board();

    // Function which prints an image of the board showing hits ( X ) and misses ( O )
    void PrintBoard();


    // Resets the board for both players before new games begin
    void ResetBoard();

    // Marks both boards after each guess
    void MarkBoard(bool hit, Point guessCoordinate);

    // Returns TRUE if the user has guessed the given coordinate
    bool CheckGuess( Point guessCoordinate );


private:
    // Board used for determining whether the user has guessed a certain position yet or not 
    bool playerBoard[BOARD_WIDTH][BOARD_LENGTH] = {false};
    // Board used soley for output
    // KEY: 0 = not yet guessed, 1 = hit, 2 = miss
    // intialize all spaces to 0 to show that no guesses have been made yet
    int outputBoard[10][10] = { 0 };

};

Board.cpp

Board.cpp

// Board.cpp - Board class function implementation

#include "Board.h"


Board::Board()
{

}


// Prints the output board to console
void Board::PrintBoard()
{
    // Print column numbers
    cout << "   \t" << " " << 1;
    for( int number = 2; number < 11; number++)
        cout << " " << number;
    cout << endl;

    // Print board itself
    // i = row number, j = column number
    for( int i = 0; i < 10; i++)
    {
        // int i can double as a row and column counter for checking if a space has been hit

        /*cout << " \t";
        // Print row lines
        for( int k = 1; k < 11; k++)
            cout << " __";*/
        cout << endl;
        // Print row number
        cout << i+1 << " ";
        cout << "\t";
        // Print columns 
        for( int j = 0; j < 10; j++)
        {
            cout << "|";

            // INSERT CODE THAT PLACES X OR O IF GUESS IS HIT OR SHIP
            if( outputBoard[i][j] == 0 )
                cout << WATER;
            if( outputBoard[i][j] == 1 )
                cout << HIT;
            if( outputBoard[i][j] == 2 )
                cout << MISS;

        }
        cout << "|";
        cout << endl;
    }
    cout << endl;
}


void Board::MarkBoard(bool hit, Point guessCoordinate)
{
    // First mark the board to show the player has guessed this coordinate
    playerBoard[guessCoordinate.X][guessCoordinate.Y] = true;

    if( hit == true )
    {
        // Show that the player hit a ship
        outputBoard[guessCoordinate.X][guessCoordinate.Y] = 1;
    }
    else
    {
        // Show that the player missed the ship
        outputBoard[guessCoordinate.X][guessCoordinate.Y] = 2;
    }
}


bool Board::CheckGuess(Point guessCordinate)
{
    bool previouslyGuessed = false;

    // If the given point has already been guessed, make the function return true
    if( playerBoard[guessCordinate.X][guessCordinate.Y] )
    {
        previouslyGuessed = true;
    }

    else
    {
        previouslyGuessed = false;
    }

    return previouslyGuessed;
}

Ship.h

Ship.h

#pragma once

#include <string>
#include "Point.h"
using namespace std;

#define SHIP_TYPES 5
#define MAX_LENGTH 5



enum DIRECTION {HORIZONTAL,VERTICAL};



class Ship
{
public:
    // Constructor
    Ship();

    // Function to initially set all ship to the correct values
    void LoadShips( Ship ship[SHIP_TYPES] );

    // Function which gives ships their location points and placement orientation
    void FillShipData( DIRECTION direction, Point coordinate );

    bool isSunk();

    bool isHit( Point guess, Ship ship[SHIP_TYPES] );

    string GetName()
    { return Name; }



private:
    // Ship name
    string Name;
    // How many spaces the ship occupies
    int Length;
    // Determines whether a ship lies vertically or horizontally on the board
    DIRECTION Direction;
    // Holds the coordinates that the ship occupies
    Point spaceOccupied[MAX_LENGTH];

};

Ship.cpp

Ship.cpp

#include "Ship.h"


Ship::Ship()
{

}


void Ship::LoadShips(Ship ship[SHIP_TYPES])
{
    //Sets the default data for the ships
    //we plan to include in the game
    //IMPORTANT!! > MUST MATCH SHIP_TYPES -Default=5 (0-4)
    ship[0].Name = "Cruiser"; ship[0].Length = 2;
    ship[1].Name = "Frigate"; ship[1].Length = 3;
    ship[2].Name = "Submarine"; ship[2].Length = 3;
    ship[3].Name = "Escort"; ship[3].Length = 4;
    ship[4].Name = "Battleship"; ship[4].Length = 5;
}






void Ship::FillShipData( DIRECTION direction, Point coordinate )
{
    Direction = direction;
    int x,y;

    // If the ship will be laid horizontally, give it the initial point plus the x-coordinates to its right 
    if( Direction == HORIZONTAL )
    {
        while( coordinate.X+Length >= BOARD_WIDTH || coordinate.X < 0 || coordinate.Y < 0 || coordinate.Y >= BOARD_LENGTH )
        {
            cout << "Your ship will not be entirely on the board when placed this way. Please choose a new row number and column number separated by a space (ex: x y): ";
            cin >> x >> y;
            coordinate.X = x;
            coordinate.Y = y;

        }

        for( int i = 0; i < Length; i++ )
        {
            spaceOccupied[i] = coordinate;
            coordinate.X++;
        }
    }

    // If the ship will be laid vertically, give it the initial point plus the y-coordinates below it
    else
    {
        // Be sure the give point will contain and the ship
        while( coordinate.Y+Length >= BOARD_LENGTH || coordinate.X < 0 || coordinate.Y < 0 || coordinate.X >= BOARD_WIDTH )
        {
            cout << "Your ship will not be entirely on the board when placed this way. Please choose a new row number and column number separated by a space (ex: x y): ";
            cin >> x >> y;
            coordinate.X = x;
            coordinate.Y = y;

        }

        for( int i = 0; i < Length; i++ )
        {
            spaceOccupied[i] = coordinate;
            coordinate.Y++;
        }
    }
}






// use throwaway to call, one user's guess and the other user's ships
// 
bool Ship::isHit( Point guess, Ship ship[SHIP_TYPES] )
{
    bool hit = false;

    // For loop to examine each ship
    for( int i = 0; i < SHIP_TYPES && hit==false; i++ )
    {
        // For loop to go through each point the ship occupies
        for( int j = 0; j < ship[i].Length && hit==false; j++ )
        {
            // If the player's guess matches a point the ship is located on, it has been hit
            if( ship[i].spaceOccupied[j] == guess )
            {
                hit = true;

                // Inform player they landed a hit
                cout << "Ship: " << ship[i].Name << " has been hit!\n";
            }
        }
    }

    // If the player has missed all ships, inform them
    if( hit == false )
        cout << "Missed.\n";


    return hit;
}

And finally Point.h

最后 Point.h

#pragma once

#include <iostream>
using namespace std;

#define BOARD_LENGTH 10
#define BOARD_WIDTH 10

struct Point
{
    // A location on the grid defined
    // by X(horizontal) Y(vertical) coordinates
    int X;
    int Y;

    bool operator == (const Point& compareTo) const
    {
        return ( (X == compareTo.X) && (Y == compareTo.Y) );
    }

};



ostream& operator <<(ostream& out, const Point& myPoint)
{
    out << "(" << myPoint.X << "," << myPoint.Y << ")";
    return out;
}

My main function simply includes Board.h and Ship.h with no function declarations. Any help would be greatly appreciated!

我的主要函数只包括 Board.h 和 Ship.h,没有函数声明。任何帮助将不胜感激!

回答by Adam Waite

Stupid one, but make sure you haven't #imported a .m file by mistake somewhere

愚蠢的,但请确保您没有在某处错误地#imported .m 文件

回答by Phillip Kinkade

The problem is that you are redefining the operator<<(ostream&, const Point&)in main.cpp Board.cpp, and Ship.cpp by including Point.h in each.

问题是您正在重新定义operator<<(ostream&, const Point&)main.cpp Board.cpp 和 Ship.cpp 中的 Point.h。

You can most easily solve this problem by making it inline, in Point.h.

您可以通过inline在 Point.h 中制作它来最轻松地解决此问题。

inline ostream& operator <<(ostream& out, const Point& myPoint) // << add inline

When you see those strange symbol names in the error output, a trick is to use c++filtin your Terminal to see more easily what the function name or symbol is that causing the problem. This "unmangles" the symbol name, for example, try this in Terminal:

当您在错误输出中看到那些奇怪的符号名称时,一个技巧是c++filt在您的终端中使用以更轻松地查看导致问题的函数名称或符号是什么。这“解开”了符号名称,例如,在终端中试试这个:

phillip / $ c++filt __ZlsRNSt3__113basic_ostreamIcNS_11char_traitsIcEEEERK5Point
operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Point const&)
phillip / $ 

回答by yngccc

add inlinehere.

添加inline到这里。

inline ostream& operator <<(ostream& out, const Point& myPoint)
^^^^^^
{
    out << "(" << myPoint.X << "," << myPoint.Y << ")";
    return out;
}

回答by Hypothetical inthe Clavicle

Chances are that you have object files (.o) in your Xcode project. Xcode doesn't like this. Remove the object files and the code should compile.

很有可能您的 Xcode 项目中有目标文件 (.o)。Xcode 不喜欢这样。删除目标文件,代码应该可以编译。