无缘无故地定义多个析构函数

Multiple destructor definition for no reason

本文关键字:析构函数 定义 无缘无故      更新时间:2023-10-16

我有一个项目,我从VC6迁移到VS2013。当我在构建项目时,我得到了这个错误。

error LNK2005: "public: virtual __thiscall CMemDC::~CMemDC(void)"(??1CMemDC@@UAE@XZ)已经在GameBoard.obj中定义

以下是可能导致此问题的文件。

GameBoard.h

#include "DirectSound.h"
#include "MIDI.h"
#include <vector>
class CGameBoard : public CWnd
{
    friend class CTetrisDlg;
    friend class COptionsDlg;
    DECLARE_DYNAMIC(CGameBoard);
// Construction/Destruction
public:
    CGameBoard();
    virtual ~CGameBoard();
.......
};

GameBoard.cpp文件有这个析构函数的定义。

#include "stdafx.h"
#include "Tetris.h"
#include "GameBoard.h"
#include "Piece.h"
#include "MemDC.h"
#include "VolumeCtrl.h"
#include <stdlib.h>
#include <time.h>
static CGameBoard * gpGameBoard;
CGameBoard::CGameBoard()
{
    m_pCurPiece = m_pNextPiece = 0;
    m_usLevel = 0;
    m_clrCurPiece = RGB(0,0,0);
    m_bShowGrid = TRUE;
    m_nSquareWidth = 14;
    m_nSquareHeight = 14;
    m_clrBackground = RGB(255, 255, 255);
    m_bExFigures = FALSE;
    m_pMusic = 0;
    m_uTimer = 0;
    m_dwVolume = 100;   // 100% music volume by default
    gpGameBoard = this;
}
CGameBoard::~CGameBoard()
{
    if(m_pCurPiece)
        delete m_pCurPiece;
    if(m_pNextPiece)
        delete m_pNextPiece;
    if( m_pMusic )
        delete m_pMusic;
    gpGameBoard = 0;
}

此析构函数仅在GameBoard.cpp中定义一次,GameBoard不包含在任何其他cppheader file中。

MemDC.h

#ifndef _MEMDC_H_
#define _MEMDC_H_
class CMemDC : public CDC {
private:
    CBitmap m_bitmap;       // Offscreen bitmap
    CBitmap* m_oldBitmap;   // bitmap originally found in CMemDC
    CDC* m_pDC;             // Saves CDC passed in constructor
    CRect m_rect;           // Rectangle of drawing area.
    BOOL m_bMemDC;          // TRUE if CDC really is a Memory DC.
public:
    CMemDC(CDC* pDC) : CDC(), m_oldBitmap(NULL), m_pDC(pDC)
    {
        ASSERT(m_pDC != NULL); // If you asserted here, you passed in a NULL CDC.
        m_bMemDC = !pDC->IsPrinting();
        if (m_bMemDC){
            // Create a Memory DC
            CreateCompatibleDC(pDC);
            pDC->GetClipBox(&m_rect);
            m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
            m_oldBitmap = SelectObject(&m_bitmap);
            SetWindowOrg(m_rect.left, m_rect.top);
        } else {
            // Make a copy of the relevent parts of the current DC for printing
            m_bPrinting = pDC->m_bPrinting;
            m_hDC = pDC->m_hDC;
            m_hAttribDC = pDC->m_hAttribDC;
        }
    }
    ~CMemDC()
    {
        if (m_bMemDC) {
            // Copy the offscreen bitmap onto the screen.
            m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
                            this, m_rect.left, m_rect.top, SRCCOPY);
            //Swap back the original bitmap.
            SelectObject(m_oldBitmap);
        } else {
            // All we need to do is replace the DC with an illegal value,
            // this keeps us from accidently deleting the handles associated with
            // the CDC that was passed to the constructor.
            m_hDC = m_hAttribDC = NULL;
        }
    }
    // Allow usage as a pointer
    CMemDC* operator->() {return this;}
    // Allow usage as a pointer
    operator CMemDC*() {return this;}
};
#endif

这个问题与这里定义的一个定义规则有关,但我不知道该怎么做。

我已经做了这里建议的一些更改。现在我得到了下面的错误。有什么主意吗?

错误LNK1181:不能打开输入文件"Nafxcwd"。自由Libcmtd.lib '

最后以下设置帮助我解决了这个问题。

  1. Project properties->linker->input->ignore specific default library ..设置为…nafxcw.lib libcmt.lib
  2. Project properties->c/c++->Code generation->run time library ..设置为…Multi threaded DLL (/MD)
  3. Project properties->configuration properties->general->Use of MFC ..设置为…use of MFC in a shared DLL

除了这些设置之外,我没有在代码中更改任何内容(例如包括守护符等)

您没有提供完整的代码。但总的来说,你的代码似乎缺少标题保护。这些是必要的,如果没有它们,你很可能会遇到像你这样的链接器问题。

在windows上,在所有头文件的顶部添加这一行:

#pragma once

一般来说,你可以在所有的编译器中使用传统的头保护符

#ifndef HEADERNAME_H
#define HEADERNAME_H
//Put content of header file here
#endif

我最近在一些旧代码中遇到了同样的问题。我认为奇怪的是,我也看到了在我的代码中定义的一个名为CMemDC的类的错误。我将类重命名为CMemJBDC,错误消失了。