C++ 'class' 类型重定义错误
C++ 'class' type redefinition error
我正在学习 Visual C++ 并从 Ivor Horton's Visual book 构建 "Sketcher" 示例程序,我能够生成工具栏、菜单图标、提示和用一些硬的绘制的矩形-编码点。添加一些鼠标处理程序和对其他几个头文件的引用后,我收到此错误:error C2011: 'CElement' : 'class' type redefinition
。
因为这个"redefinition",其他形状class抛出了40+个错误,之前基于CElement的es似乎在编译时找不到class时间,尽管 Visual Studio 的智能感知似乎可以很好地检测到它。我认为我没有遗漏任何东西,因为在我最后几次更改之前所有内容都已正确编译,但我已经用尽了我的 undo/redo 历史记录并且似乎无法找到根本原因。
我已经查看了与此错误消息相关的其他一些答案,但我仍然无法确定我的 class 第二次被定义的确切位置。
我的 Element.h 文件包含以下代码:
#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:
CPoint m_StartPoint; // Element position
int m_PenWidth; // Pen width
COLORREF m_Color; // Color of an element
CRect m_EnclosingRect; // Rectangle enclosing an element
// Create a pen
void CreatePen(CPen& aPen);
public:
virtual ~CElement();
virtual void Draw(CDC* pDC) {} // Virtual draw operation
// Get the element enclosing rectangle
const CRect& GetEnclosingRect() const { return m_EnclosingRect; }
protected:
// Constructors protected so they cannot be called outside the class
CElement();
CElement(const CPoint& start, COLORREF color, int penWidth = 1);
};
我的 Element.cpp 文件包含以下代码:
#include "stdafx.h"
#include "Element.h"
CElement::CElement()
{
}
void CElement::CreatePen(CPen& aPen)
{
if (!aPen.CreatePen(PS_SOLID, m_PenWidth, m_Color))
{
// Pen creation failed
AfxMessageBox(_T("Pen creation failed."), MB_OK);
AfxAbort();
}
}
CElement::~CElement()
{
}
建议:在头文件的 ALL 中使用 include guard:
Element.h:
#ifndef ELEMENT_H
#define ELEMENT_H
#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:
CPoint m_StartPoint; // Element position
...
protected:
// Constructors protected so they cannot be called outside the class
CElement();
CElement(const CPoint& start, COLORREF color, int penWidth = 1);
};
#endif
正如 FoggyDay 所说,您应该避免成为 re-included class header。
另一种更简单的方法是将“#pragma once”放在 header 的顶部。
喜欢
#pragma once
#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:
你没有展示足够的代码(更好的是,你会提供一个 MCVE)所以很难确定。
然而,最可能的解释是 Element.h 在某些编译单元中被 #include
d 不止一次。这种多重包含可能是间接的(例如,源文件包含两个(或更多)不同的 header,每个 #include "Element.h"
)。最终结果是编译器不止一次看到 CElement
的定义。因此出现错误 - 在任何编译单元中这样的多重定义都是非法的。
通常的解决方案是修改 Element.h 并包含 guards
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_HEADER
// the current content of the Element.h
#endif
这样做的结果是,当 Element.h 多次 #include
d 时,定义不会被复制。
有些人会告诉您在 header 中使用 #pragma once
。该方法的问题在于它特定于某些编译器,但不适用于所有编译器(即使它适用于许多编译器)。 Pragmas 是标准提供的钩子,可启用 compiler-specific 扩展。更糟糕的是,不支持 #pragma once
(或与此相关的任何其他 pragma)的编译器通常会简单地忽略它们而不发出诊断 - 因为这是标准所要求的。
我正在学习 Visual C++ 并从 Ivor Horton's Visual book 构建 "Sketcher" 示例程序,我能够生成工具栏、菜单图标、提示和用一些硬的绘制的矩形-编码点。添加一些鼠标处理程序和对其他几个头文件的引用后,我收到此错误:error C2011: 'CElement' : 'class' type redefinition
。
因为这个"redefinition",其他形状class抛出了40+个错误,之前基于CElement的es似乎在编译时找不到class时间,尽管 Visual Studio 的智能感知似乎可以很好地检测到它。我认为我没有遗漏任何东西,因为在我最后几次更改之前所有内容都已正确编译,但我已经用尽了我的 undo/redo 历史记录并且似乎无法找到根本原因。
我已经查看了与此错误消息相关的其他一些答案,但我仍然无法确定我的 class 第二次被定义的确切位置。
我的 Element.h 文件包含以下代码:
#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:
CPoint m_StartPoint; // Element position
int m_PenWidth; // Pen width
COLORREF m_Color; // Color of an element
CRect m_EnclosingRect; // Rectangle enclosing an element
// Create a pen
void CreatePen(CPen& aPen);
public:
virtual ~CElement();
virtual void Draw(CDC* pDC) {} // Virtual draw operation
// Get the element enclosing rectangle
const CRect& GetEnclosingRect() const { return m_EnclosingRect; }
protected:
// Constructors protected so they cannot be called outside the class
CElement();
CElement(const CPoint& start, COLORREF color, int penWidth = 1);
};
我的 Element.cpp 文件包含以下代码:
#include "stdafx.h"
#include "Element.h"
CElement::CElement()
{
}
void CElement::CreatePen(CPen& aPen)
{
if (!aPen.CreatePen(PS_SOLID, m_PenWidth, m_Color))
{
// Pen creation failed
AfxMessageBox(_T("Pen creation failed."), MB_OK);
AfxAbort();
}
}
CElement::~CElement()
{
}
建议:在头文件的 ALL 中使用 include guard:
Element.h:
#ifndef ELEMENT_H
#define ELEMENT_H
#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:
CPoint m_StartPoint; // Element position
...
protected:
// Constructors protected so they cannot be called outside the class
CElement();
CElement(const CPoint& start, COLORREF color, int penWidth = 1);
};
#endif
正如 FoggyDay 所说,您应该避免成为 re-included class header。
另一种更简单的方法是将“#pragma once”放在 header 的顶部。
喜欢
#pragma once
#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:
你没有展示足够的代码(更好的是,你会提供一个 MCVE)所以很难确定。
然而,最可能的解释是 Element.h 在某些编译单元中被 #include
d 不止一次。这种多重包含可能是间接的(例如,源文件包含两个(或更多)不同的 header,每个 #include "Element.h"
)。最终结果是编译器不止一次看到 CElement
的定义。因此出现错误 - 在任何编译单元中这样的多重定义都是非法的。
通常的解决方案是修改 Element.h 并包含 guards
#ifndef SOME_MACRO_UNIQUE_TO_YOUR_HEADER
#define SOME_MACRO_UNIQUE_TO_YOUR_HEADER
// the current content of the Element.h
#endif
这样做的结果是,当 Element.h 多次 #include
d 时,定义不会被复制。
有些人会告诉您在 header 中使用 #pragma once
。该方法的问题在于它特定于某些编译器,但不适用于所有编译器(即使它适用于许多编译器)。 Pragmas 是标准提供的钩子,可启用 compiler-specific 扩展。更糟糕的是,不支持 #pragma once
(或与此相关的任何其他 pragma)的编译器通常会简单地忽略它们而不发出诊断 - 因为这是标准所要求的。