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

时间:2013-11-25 04:05:02

标签: c++ xcode

当我尝试编译并且不知道为什么

时,我一直收到此错误
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)

我的标题和.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 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

#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

#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;
}

最后是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;
}

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

4 个答案:

答案 0 :(得分:7)

愚蠢的一个,但要确保你没有错误地#imp一个.m文件

答案 1 :(得分:2)

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

您最容易通过在Point.h中将其inline解决来解决此问题。

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

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

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

答案 2 :(得分:1)

在这里添加inline

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

答案 3 :(得分:0)

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