【发布时间】:2014-01-11 12:53:32
【问题描述】:
可能重复:link
大家好,
关于静态成员变量,我不明白一件奇怪的事情。如果静态变量的“定义”(我不确定它是否正确)在类的头文件中,编译器会给出链接错误,但是如果它们在 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 : 错误 LNK2005: "private: static enum ChessViewConstants::MENU_STATE UserInterface::m_displayState" (?m_displayState@UserInterface@@0W4MENU_STATE@ChessViewConstants@@A) 已经在 Execution.obj 中定义 1>MasterController.obj : 错误 LNK2005: "private: static struct ChessModelConstants::PieceMovement UserInterface::m_pieceMovement" (?m_pieceMovement@UserInterface@@0UPieceMovement@ChessModelConstants@@A) 已经在 Execution.obj 中定义 1>UserInterface.obj : error LNK2005: "private: static bool UserInterface::m_undoRequested" (?m_undoRequested@UserInterface@@0_NA) 已经在 Execution.obj 中定义 1>UserInterface.obj : error 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) 已经在 Execution.obj 中定义 1>D:\C++\CheatersChess\Debug\CheatersChess.exe : 致命错误 LNK1169: 找到一个或多个多重定义符号
【问题讨论】:
-
您的第二个问题完全不清楚。该结构有一个默认构造函数,而且这些数据成员是公共的,那么它们的初始化有什么问题?!
-
如果你有两个问题,也许你应该问两个不同的问题。
-
嗯,有些情况下我想声明静态对象类型成员。我想用 object->initialize() 或类似的东西来初始化它。当然我只想初始化一次。那我该怎么做呢?我不能在构造函数中做到这一点,唯一的选择似乎是制作
#define ObjectInitialized 1那种我想避免的事情。 -
你不能在函数体之外调用像
object->initialize()这样的函数。因此,对于静态对象的定义,不能使用initialize()这样的成员函数;您必须在构造函数中执行此操作(但构造函数当然可以调用initialize())。如果由于某种原因这对你来说真的绝对不可能,那么作为最后的手段,你可以定义一个不同类型的单独全局对象,并确保该对象的构造函数调用第一个对象的initialize()函数。
标签: c++ class variables static member