今天coding时遇到一个大问题,这个问题之前在看Effective C++中的条款term07时遇到过!今天总结记录一下!方便日后再次遇到时可以反应过来!
请看以下代码:
gun.h和gun.cpp:
//gun.h
#pragma once
#include<iostream>
#include<string>
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<iostream>
#include<string>
#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<iostream>
#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<iostream>
#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(){
//空实现!
}