无故定义多个析构函数

Posted

技术标签:

【中文标题】无故定义多个析构函数【英文标题】:Multiple destructor definition for no reason 【发布时间】:2015-08-14 11:18:22 【问题描述】:

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

错误 LNK2005:“公共:虚拟 __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

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

我已经做了一些建议here 的更改。现在我遇到了以下错误。有什么想法吗?

错误 LNK1181:无法打开输入文件“Nafxcwd.lib Libcmtd.lib”

【问题讨论】:

错误是指CMemDC::~CMemDC(void)而不是GameBoard的析构函数。您是否可能在某处缺少包含守卫? @odyss-jii *包含警卫 -- 包含语句?添加以供参考。 它没有说明定义析构函数的其他文件吗? 您还没有发布相关来源。问题在于CMemDC析构函数。 @skyking 不,它什么也没说。我检查了其他文件中的析构函数定义,但它不存在。我添加了构造函数定义以供参考,请。 【参考方案1】:

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

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

#pragma once

一般而言,您可以在所有编译器中使用传统的标头保护

#ifndef HEADERNAME_H
#define HEADERNAME_H

//Put content of header file here

#endif

【讨论】:

#ifndef _MEMDC_H #define MEMDC_H MemDC.h 在文件顶部有这个代码。 这也是错误的。查看名称,您在#ifndef 中使用MEMDC_H,在#define 中使用_MEMDC_H_。使用相同的名称。 我检查过,名字写得对。我已经添加了#pragma once,但没有运气:(【参考方案2】:

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

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

除了这些设置之外,我没有更改代码中的任何内容(w.r.t. 包括警卫等)

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于无故定义多个析构函数的主要内容,如果未能解决你的问题,请参考以下文章

C++学习之类的构造函数析构函数

关于类继承的构造与析构调用分析

C++构造/析构/赋值函数

mfc 类的析构函数

虚函数构造和析构函数执行顺序总结

C++析构函数定义和使用