C ++'class'类型重定义错误

时间:2016-05-29 05:33:02

标签: c++ visual-c++ compiler-errors header-files redefinition

我正在学习Visual C ++并从Ivor Horton's Visual book构建“Sketcher”示例程序,我能够生成工具栏,菜单图标,提示和用几个硬编码点绘制的矩形。添加一些鼠标处理程序和对其他一些头文件的引用后,我收到此错误:error C2011: 'CElement' : 'class' type redefinition

由于这种“重新定义”,以前基于CElement的其他形状类中抛出的40多个错误似乎无法在编译时找到该类,尽管Visual Studio的intellisense似乎检测到它很好。我不认为我错过任何东西,因为在我最后几次更改之前所有内容都已正确编译,但我已经用尽了我的撤销/重做历史,似乎无法找到根本原因。

我已经查看了与此错误消息相关的其他一些答案,但我仍然坚持精确定位第二次定义我的课程的位置。

我的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()
{
}

3 个答案:

答案 0 :(得分:2)

建议:在头文件的 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

答案 1 :(得分:1)

正如FoggyDay所说,你应该避免被重新包括在课程标题中。

另一个更简单的方法就是把#34; #pragma一次&#34;在标题的顶部。

#pragma once

#include <algorithm>
#include "stdafx.h"
class CElement : public CObject
{
protected:

答案 2 :(得分:1)

您还没有显示足够的代码(更好的是,您会提供MCVE),因此很难确定。

但是,最可能的解释是,在某些编译单元中,Element.h不止一次#include。该多重包含可以是间接的(例如,源文件包括每个#include "Element.h")的两个(或更多个)不同的头部。最终结果是编译器不止一次地看到CElement的定义。因此错误 - 任何编译单元中的这种多重定义都是非法的。

通常的解决方案是使用include guards修改Element.h

#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时,定义不会被复制。

有些人会告诉您在标题中使用#pragma once。这种方法的问题在于它特定于某些编译器,但不适用于所有编译器(即使它与许多编译器一起使用)。 Pragma是标准提供的钩子,它支持特定于编译器的扩展。更糟糕的是,不支持#pragma once(或任何其他编译指示)的编译器通常只是忽略它们而不发布诊断 - 因为这是所有标准要求。