c++ - 应该是虚拟析构函数?但是怎么做?
问题描述
将电话公司的消费者数据存储在链接列表中的程序。最后,它显示每个人的账单。我有以下代码:
class BaseTypeOfContract
{
private:
int minutePrice;
int SMSPrice;
public:
void setminutePrice(int x) { minutePrice = x; }
void setSMSPrice(int x) { SMSPrice = x; }
virtual int calculateBill(int talkedMinutes, int sentSMS) = 0;
int getminutePrice() const { return minutePrice; }
int getSMSPrice() const { return SMSPrice; }
};
class SMSBaseType : public BaseTypeOfContract
{
private:
int freeSMS;
public:
SMSBaseType(int minutePrice, int SMSPrice, int freeSMS)
{
setminutePrice(minutePrice);
setSMSPrice(SMSPrice);
setfreeSMS(freeSMS);
}
public:
void setfreeSMS(int free) { this->freeSMS = free; }
virtual int calculateBill(int talkedMinutes, int sentSMS)
{
int billedSMS = (freeSMS > sentSMS) ? 0 : sentSMS - freeSMS;
return talkedMinutes * getminutePrice() + billedSMS * getSMSPrice();
}
};
class Base : public BaseTypeOfContract
{
public:
Base()
{
setminutePrice(30);
setSMSPrice(10);
}
virtual int calculateBill(int talkedMinutes, int sentSMS) { return talkedMinutes * getminutePrice() + sentSMS * getSMSPrice();}
};
class SMSMax : public SMSBaseType
{
public:
SMSMax() : SMSBaseType(20, 5, 150) {}
};
class MobiNET: public SMSBaseType
{
public:
MobiNET() : SMSBaseType(10, 15, 25) {}
};
客户类别:
class Client
{
public:
std::string name;
std::string phoneNumber;
BaseTypeOfContract* typeOfContract;
int talkedMinutes;
int sentSMS;
Client *next;
public:
Client(){}
Client(std::string n, std::string p, int bp, int ks) : name(n), phoneNumber(p), talkedMinutes(bp), sentSMS(ks) {}
void preSetPlan(std::string s)
{
if (s == "MobiNET")
this->typeOfContract = new MobiNET();
else if (s == "SMSMax")
this->typeOfContract = new SMSMax();
else this->typeOfContract = new Base();
}
std::string getname() const { return name; }
std::string getphoneNumber() const { return phoneNumber; }
void setname(std::string n) { name = n; }
void setphoneNumber(std::string pn) { phoneNumber = pn; }
void settalkedMinutes(int bp) { talkedMinutes = bp; }
void setsentSMS(int SSMS) { sentSMS = SSMS; }
int getBill() const { return this->typeOfContract->calculateBill(talkedMinutes, sentSMS); }
};
我从 2 个文件中读取数据。第一个文件包含姓名、电话号码、合同类型。第二个文件包含电话号码、通话时间和发送的短信。
Client* file_read_in()
{
std::ifstream ClientData;
ClientData.open("clients.txt");
Client *first = new Client;
first = NULL;
while (!ClientData.eof())
{
std::string name, phoneNumber, typeOfContract;
ClientData >> name;
ClientData >> phoneNumber;
ClientData >> typeOfContract;
std::ifstream ClientTalkedSent;
ClientTalkedSent.open("used.txt");
while(!ClientTalkedSent.eof())
{
std::string phoneNumber2;
ClientTalkedSent >> phoneNumber2;
if (phoneNumber2 == phoneNumber)
{
int talkedMinutes, sentSMS;
ClientTalkedSent >> talkedMinutes;
ClientTalkedSent >> sentSMS;
Client* tmp = new Client(name, phoneNumber, talkedMinutes, sentSMS);
tmp->preSetPlan(typeOfContract);
tmp->next = NULL;
if (first == NULL)
{
first = tmp;
}
else
{
Client *cond = first;
while (cond->next != NULL) cond = cond->next;
cond->next = tmp;
}
}
}
ClientTalkedSent.close();
}
ClientData.close();
return first;
}
主要的:
int main()
{
Client* first = file_read_in();
while(first != NULL)
{
std::cout << first->getname() << " " << first->getphoneNumber() << " " << first->getBill() << std::endl;
first = first->next;
}
return 0;
}
我的问题是我应该释放分配的内存,但我知道如何。哪个类的析构函数应该做脏活。如果有人可以使用我的代码来展示“析构函数继承”的工作原理,我将不胜感激。
抱歉我的英语不好,感谢您的帮助。这个网站帮助了我很多次,但对于这个问题我没有找到解决方案。
解决方案
如果您有一个BaseTypeOfContract* typeOfContract;
用于指向不同派生类的指针,则BaseTypeOfContract
需要有一个虚拟析构函数delete typeOfContract
才能工作。
并且Client
似乎创建了指向的对象,它也应该负责清理它们。通过delete typeOfContract;
在其析构函数中使用,或者通过存储智能指针来自动完成工作。
另一部分是每个Client
存储指向下一个的指针Client
。这似乎不是最好的设计。在现实生活中,根本不像每个人都知道谁是下一个在同一家商店购买手机的人。:-)
使用容器会更好,例如std::vector<Client>
,它也可以处理Client
对象的生命周期。
推荐阅读
- jquery - 自动搜索键触发两次
- python - 如何用括号和逗号而不是冒号来可视化字典
- android - 我如何制作一个按钮,以便当我将它的一部分放在边界之外时,程序不只是剪切它不是入站的部分
- spring - 春季内容。Hibernate 执行 3 次查询以获取每个产品的图像
- c# - 动态 JSON 对具有公共前缀的数据应该进入字典的位置进行建模
- angular - NativeScript Angular + Karma - ReferenceError:未定义窗口
- django - 使用 ManyToManyField 时 Django 冲突错误
- reactjs - 在 React 中将函数从父级传递给子级,以便子级可以更新父级的状态是一种反模式吗?
- excel - 如何在excel中一键向下钻取数据?
- ios - 为什么 Firebase 消息 ID 的格式不同?