为多态基类定义纯虚析构函数时必须给其一个空实现代码

为多态基类定义纯虚析构函数时必须给其一个空实现代码,第1张

为多态基类定义纯虚析构函数时必须给其一个空实现代码

        今天coding时遇到一个大问题,这个问题之前在看Effective C++中的条款term07时遇到过!今天总结记录一下!方便日后再次遇到时可以反应过来!

请看以下代码:

gun.h和gun.cpp:

//gun.h
#pragma once
#include
#include
using namespace std;
class Gun
{
public:
    string m_gunName;
    int m_bulletNUms;
public:
    Gun(const string& gun, int bulletNUms) :m_gunName(gun), m_bulletNUms(bulletNUms) {}
    void pushBullet();//zhuang bullets
    void popBullet();//fashe bullets
    void showGunInfo();
    ~Gun();
};
//gun.cpp
#include"gun.h"
//zhuang bullets
void Gun::pushBullet() {
    m_bulletNUms += 10;
}
//fashe bullets
void Gun::popBullet() {
    if (m_bulletNUms <= 0) {
        cout << "fired out! now you have no bullets!" << endl;
        return;
    }
    m_bulletNUms--;
}
void Gun::showGunInfo() {
    cout << "GunName: " << this->m_gunName << endl;
    cout << "GunBulletNums remains: " << this->m_bulletNUms << " bullets!" << endl;
}
Gun::~Gun() {

}

soldier.h和soldier.cpp:

//soldier.h
#pragma once
#include
#include
#include"gun.h"
using namespace std;
class Soldier
{
public:
    string m_Name;
    Gun m_Gun;
public:
    Soldier(const string& name, const Gun& gun) :m_Name(name), m_Gun(gun) {}
    virtual void fire() = 0;
    virtual void fullGunBullets() = 0;
    virtual ~Soldier();
};

//soldier.cpp
#include"soldier.h"
//此时我没有写任何codes给这个头文件

xusanduo.h和xusanduo.cpp:

//xusanduo.h
#pragma once
#include
#include"soldier.h"
using namespace std;
class Xusanduo : public Soldier {
public:
    Xusanduo(const string& name, const Gun& gun) :Soldier(name, gun) {}
    virtual void fire();
    virtual void fullGunBullets();
    ~Xusanduo();
};

//xusanduo.cpp
#include"xusanduo.h"

void Xusanduo::fire() {
    cout << this->m_Name << " fired!" << endl;
    this->m_Gun.popBullet();
}
void Xusanduo::fullGunBullets() {
    cout << "full 10 Bullets !" << endl;
    this->m_Gun.pushBullet();
}
Xusanduo::~Xusanduo() {
    cout << "hhh" << endl;
}

main.cpp:

#include
#include"gun.h"
#include"xusanduo.h"
#include"soldier.h"
using namespace std;
int main(void) {
	Gun myGun("AK47", 42);
	Xusanduo x("Xusanduo", myGun);
	x.fire();
	x.fullGunBullets();
	return 0;
}

当你在VS2022下按ctrl+f5 build时,会报如下错误信息:

.obj : error LNK2019: 无法解析的外部符号 "public: virtual __cdecl Soldier::~Soldier(void)" (??1Soldier@@UEAA@XZ),函数 "public: virtual void * __cdecl Soldier::`scalar deleting destructor'(unsigned int)" (??_GSoldier@@UEAAPEAXI@Z) 中引用了该符号

        这堆代码让人看不懂!!!平时我们用纯虚的形式(virtual XXX() =0;)来声明一个类成员函数时都不需要给其一份实现代码。但是, 这里是纯虚析构函数,和普通的成员函数是不一样的!究其原因是:

        当多态基类的析构函数被声明为纯虚函数时,必须给其一份空实现!(from Effective C++ term 07 -》对应该书上的P43页)

所以将base class的soldier的.cpp文件改写为:

#include"soldier.h"

Soldier::~Soldier(){ 
//空实现!
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5670390.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存