Возможный дубликат: ссылка
Всем привет,
Есть странная вещь, которую я не понимаю в статических переменных-членах. Если «определение» (я не уверен, что это правильное слово) для статических переменных находится в файле заголовка класса, компилятор выдает ошибки связывания, однако, если они находятся в файле cpp, все в порядке.
У меня есть такой класс (не вставлял все):
UserInterface.h
class UserInterface
{
public:
UserInterface(void);
~UserInterface(void);
// Some method declarations here
private:
// Some more methods declarations here
// VARIABLES
static bool m_undoRequested;
static ChessViewConstants::MENU_STATE m_displayState;
static ChessModelConstants::PieceMovement m_pieceMovement;
};
// THESE DO NOT WORK (linking errors)
//bool UserInterface::m_undoRequested = false;
//ChessViewConstants::MENU_STATE UserInterface::m_displayState = ChessViewConstants::MAIN_MENU;
//ChessModelConstants::PieceMovement UserInterface::m_pieceMovement(1, 1, 1, 1);
UserInterface.cpp
#include "UserInterface.h"
// These do work.
bool UserInterface::m_undoRequested = false;
ChessViewConstants::MENU_STATE UserInterface::m_displayState = ChessViewConstants::MAIN_MENU;
ChessModelConstants::PieceMovement UserInterface::m_pieceMovement(1, 1, 1, 1);
// Implementation....
ChessConstants.h
namespace ChessModelConstats{
// Some stuff here...
struct PieceMovement {
// A simple Constructor
PieceMovement(int originRow = -1, int originCol = -1,
int targetRow = -1, int targetCol = -1)
: m_originRow(originRow), m_originCol(originCol),
m_targetRow(targetRow), m_targetCol(targetCol)
{
}
// Members
int m_originRow;
int m_originCol;
int m_targetRow;
int m_targetCol;
};
// More stuff here....
}
Итак, почему статические переменные должны быть реализованы внутри файла cpp? Почему я не могу добавить в конец файла заголовка?
Второй вопрос: как я могу инициализировать структурную переменную (m_pieceMovement) следующим образом:
m_pieceMovement.m_originCol = -1;
m_pieceMovement.m_originRow = -1;
m_pieceMovement.m_targetCol = -1;
m_pieceMovement.m_targetRow = -1;
Кажется, мне здесь не хватает фундаментальной информации, не стесняйтесь давать советы новичкам тут и там :)
Заранее спасибо,
Джон Джон
РЕДАКТИРОВАТЬ: Вот ошибки связывания:
1> MasterController.obj: ошибка LNK2005: «private: static bool UserInterface :: m_undoRequested» (? M_undoRequested @ UserInterface @@ 0_NA) уже определен в Execution.obj 1> MasterController.obj: error LNK2005: «private: static enum ChessViewConstants: : MENU_STATE UserInterface :: m_displayState "(? M_displayState @ UserInterface @@ 0W4MENU_STATE @ ChessViewConstants @@ A), уже определенный в Execution.obj 1> MasterController.obj: error LNK2005: "ove private: static struct ChessInModelConstants :: PieceModelConstants :: PieceModelConstants :: Piece (? m_pieceMovement @ UserInterface @@ 0UPieceMovement @ ChessModelConstants @@ A) уже определено в Execution.obj 1> UserInterface.obj: error LNK2005: «private: static bool UserInterface :: m_undoRequested» (? m_undoRequested @ UserInterface @@ уже определено 0_undoRequested @ UserInterface @@ в Execution.obj 1> UserInterface.obj: ошибка LNK2005: "private: static enum ChessViewConstants :: MENU_STATE UserInterface :: m_displayState"? m_displayState @ UserInterface @@ 0W4MENU_STATE @ ChessViewConstants @@ A) уже определено в Execution.obj 1> UserInterface.obj: ошибка LNK2005: «private: static struct ChessModelConstants :: PieceMovement UserInterface :: m_pieceMovement» (? m_pieceMovement @ UserInterface @@ 0UPieceMovement @ ChessModelConstants @@ A. уже определено в 1 >cution D: \ C ++ \ CheatersChess \ Debug \ CheatersChess.exe: фатальная ошибка LNK1169: обнаружен один или несколько многократно определенных символов
object->initialize()
вне тела функции. Следовательно, для определения статического объекта нельзя использовать функцию-член, напримерinitialize()
; вы должны сделать это в конструкторе (но конструктор, конечно, может вызыватьinitialize()
). Если по какой-то причине это действительно абсолютно невозможно для вас, то в крайнем случае вы можете определить отдельный глобальный объект другого типа и убедиться, что конструктор этого объекта вызывает функциюinitialize()
первого объекта. - person jogojapan   schedule 11.01.2014