设计计算机类的练习中出现的错误
我正在尝试设计一个计算机类,我想使用一个名为Work的函数来检查每个硬件的状态,但是在Dell / IBM类中使用时会失败(仅在PC类中使用时没有问题)。 我debug一小时没能找出错误原因。
源代码可以完成编译。
Work()位于第117行,该行具有FIXME标签
类之间的关系图在最后
这是源代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class HardWare
{
private:
string brand = "";
public:
HardWare(string bra = "") : brand(bra) {}
virtual ~HardWare() {}
virtual void Set(HardWare *obj);
virtual void work() {}
string getBrand() { return brand; }
};
void HardWare::Set(HardWare *obj)
{
brand = obj->brand;
}
class CPU : public HardWare
{
private:
double frequency = 0.0;
public:
CPU(string b = "", double f = 0.0) : HardWare(b), frequency(f) {}
virtual ~CPU() {}
virtual void Set(CPU *obj);
void work();
double getFrequency() { return frequency; }
};
void CPU::Set(CPU *obj)
{
frequency = obj->frequency;
HardWare::Set(obj);
}
void CPU::work()
{
cout << getBrand() << " CPU Work with " << frequency << "GHz\n";
}
class MainBoard : public HardWare
{
private:
string type = "";
public:
MainBoard(string b = "", string t = "") : HardWare(b), type(t) {}
virtual ~MainBoard() {}
virtual void Set(MainBoard *obj);
void work();
string getType() { return type; }
};
void MainBoard::Set(MainBoard *obj)
{
type = obj->type;
HardWare::Set(obj);
}
void MainBoard::work()
{
cout << getBrand() << " MainBoard Work with " << type << "\n";
}
class HardDisk : public HardWare
{
private:
int store = 0;
public:
HardDisk(string b = "", int s = 0) : HardWare(b), store(s) {}
virtual ~HardDisk() {}
virtual void Set(HardDisk *obj);
void work();
int getStore() { return store; }
};
void HardDisk::Set(HardDisk *obj)
{
store = obj->store;
HardWare::Set(obj);
}
void HardDisk::work()
{
cout << getBrand() << " HardDisk Work with " << store << "G\n";
}
class PC
{
private:
vector<HardWare *> computer;
public:
void AddToPC(HardWare *obj);
void Work();
};
void PC::AddToPC(HardWare *obj)
{
computer.push_back(obj);
}
//FIXME117
void PC::Work()
{
for (int i = 0; i <computer.size(); i++)
computer[i]->work();
cout << "PC Work\n";
}
class Builder
{
public:
virtual void ProduceCPU() = 0;
virtual void ProduceHardDisk() = 0;
virtual void ProduceMainBoard() = 0;
virtual void ProducePC() = 0;
virtual PC *GetPC() = 0;
};
class DellBuilder : public Builder
{
public:
virtual void ProduceCPU();
virtual void ProduceHardDisk();
virtual void ProduceMainBoard();
virtual void ProducePC();
PC *GetPC();
private:
PC *m_PC;
};
void DellBuilder:: ProduceCPU(){
string brand;
double frequency;
cin>>brand>> frequency;
cin.get();
HardWare* wcpu = new CPU(brand, frequency);
m_PC->AddToPC(wcpu);
delete wcpu;
}
void DellBuilder:: ProduceHardDisk(){
string brand;
unsigned int store;
cin>>brand >> store;
cin.get();
HardWare *wdisk = new HardDisk(brand, store);
m_PC->AddToPC(wdisk);
delete wdisk;
}
void DellBuilder:: ProduceMainBoard(){
string brand, type;
cin >> brand >> type;
cin.get();
HardWare *wboard = new MainBoard(brand, type);
m_PC->AddToPC(wboard);
delete wboard;
}
void DellBuilder:: ProducePC(){
m_PC = new PC();
}
PC * DellBuilder:: GetPC(){
return m_PC;
}
class IBMBuilder : public Builder
{
public:
virtual void ProduceCPU();
virtual void ProduceHardDisk();
virtual void ProduceMainBoard();
virtual void ProducePC();
PC *GetPC();
private:
PC *m_PC;
};
void IBMBuilder:: ProduceCPU(){
string brand;
double frequency;
cin>>brand>> frequency;
cin.get();
HardWare* wcpu = new CPU(brand, frequency);
m_PC->AddToPC(wcpu);
delete wcpu;
}
void IBMBuilder:: ProduceHardDisk(){
string brand;
unsigned int store;
cin>>brand>> store;
cin.get();
HardWare *wdisk = new HardDisk(brand, store);
m_PC->AddToPC(wdisk);
delete wdisk;
}
void IBMBuilder:: ProduceMainBoard(){
string brand, type;
cin >> brand >> type;
cin.get();
HardWare *wboard = new MainBoard(brand, type);
m_PC->AddToPC(wboard);
delete wboard;
}
void IBMBuilder:: ProducePC(){
m_PC = new PC();
}
PC * IBMBuilder:: GetPC(){
return m_PC;
}
int main()
{
cout << "\nBuilding Dell Computer\n";
Builder *pDell = new DellBuilder();
pDell->ProducePC();
pDell->ProduceCPU();
pDell->ProduceHardDisk();
pDell->ProduceMainBoard();
pDell->GetPC()->Work();
cout << "\nBuilding IBM Computer\n";
IBMBuilder *pIBM = new IBMBuilder();
pIBM->ProducePC();
pIBM->ProduceCPU();
pIBM->ProduceHardDisk();
pIBM->ProduceMainBoard();
pIBM->GetPC()->Work();
system("pause");
return 0;
}
类关系图
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
C++ 看起来比较吃力,不过在
DellBuilder::ProduceCPU()
中有这么几句wcpu
被创建出来,然后就被删掉了。AddToPC
调用了computer.push_back(obj)
,它添加的是一个指针,该指针指向一个CPU
对象。然而
delete wcpu
掉之后,computer
中的那个指针就成了一个野指针,没有指向有效的对象,再使用它的时候就肯定会出错(实体都没删了,还能干啥呢?)。代码没仔细看下去,不过,相信还有类似的问题。
那该什么时候删?
一般原则是哪里创建哪些删,但这个原则对构造,Builder,Factory 等构建类方法不适用,因为东西才创造出来,还没用呢,你就删,还怎么用呢?
理论上来说,DellBuilder 应该创建一个
pDellPc
(GetPC()
)。pDellBuilder
用完之后可以delete pDellBuilder
删除掉,但它创建出来的pDellPc
不能删。它应该在用完之后通过delete pDellPc
来删除掉。接下来,PC 中的硬件由于不需要离开 PC 单独使用,所以在 PC 的析构函数中删除掉。