我通过不同的资源阅读,但感觉我错过了什么。当变量(numItems)达到零时,我明确地调用析构函数。我有一个打印所有类对象(学生)的循环,但是任何调用析构函数的对象都有一个空白的名字和姓氏,ID和numItems变量仍然存在。我误解了析构函数是如何工作的吗?为什么要删除一些但不是全部的成员属性?
此外,“项目”存储在动态数组中。只要数组是公共的,我就可以设置和访问它们。但即使使用setter,如果我尝试填充私有数组,程序也会崩溃。
部首:
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ARRAY_MAX 15
using namespace std;
class Student
{
private:
string firstName, lastName;
unsigned int ID, numItems = 0;
typedef string* StringPtr;
//StringPtr items;
public:
int capacity = 15;
string *items = new string[capacity];
Student();
Student(const unsigned int id, const string fName, const string lName);
string getfName() const;
string getlName() const;
unsigned int getnumItems() const;
string getItem(int num);
unsigned int getID() const;
void setfName(string fname);
void setlName(string lname);
void setID(unsigned int id);
void setItem(string str, int num);
int CheckoutCount();
bool CheckOut(const string& item);
bool CheckIn(const string& item);
bool HasCheckedOut(const string& item);
void Clear();
~Student();
//const Student operator+(string rhs);
//void operator+=(string rhs);
//bool operator==(Student rhs);
friend istream& operator>>(istream& input, Student& stu);
friend ostream& operator<<(ostream& output, const Student& stu);
};
#endif // STUDENT_H
说明:
#include "student.h"
using namespace std;
Student::Student()
{
}
Student::Student(const unsigned int id, const string fName, const string lName)
{
firstName = fName;
lastName = lName;
ID = id;
}
string Student::getfName() const
{
return firstName;
}
string Student::getlName() const
{
return lastName;
}
unsigned int Student::getnumItems() const
{
return numItems;
}
string Student::getItem(int num)
{
return items[num];
}
unsigned int Student::getID() const
{
return ID;
}
void Student::setfName(string fname)
{
firstName = fname;
}
void Student::setlName(string lname)
{
lastName = lname;
}
void Student::setID(unsigned int id)
{
if ((id >= 1000) && (id <= 100000))
{
ID = id;
}
else
{
cout << "Attempted ID for " << firstName << " " << lastName << " is invalid. Must be between 1000 and 100,000." << endl;
}
}
void Student::setItem(string str, int num)
{
items[num] = str;
}
int Student::CheckoutCount()
{
return numItems;
}
bool Student::CheckOut(const string & item)
{
if (this->HasCheckedOut(item) == true)
{
return false; // already found item in list, CheckOut failed...
}
else
{
items[numItems] = item;
numItems++;
return true; // CheckOut successful
}
}
bool Student::CheckIn(const string & item)
{
for (int i = 0; i < numItems; i++)
{
if (items[i] == item)
{
for (; i < numItems - 1; i++)
{
// Assign the next element to current location.
items[i] = items[i + 1];
}
// Remove the last element as it has been moved to previous index.
items[numItems - 1] = "";
numItems = numItems - 1;
if (numItems == 0)
{
this->~Student();
}
return true;
}
}
return false;
}
bool Student::HasCheckedOut(const string & item)
{
string *end = items + numItems;
string *result = find(items, end, item);
if (result != end)
{
return true; // found value at "result" pointer location...
}
else
return false;
}
void Student::Clear()
{
ID = 0;
firstName = "";
lastName = "";
delete[] items;
}
Student::~Student()
{
}
istream & operator>>(istream & input, Student & stu)
{
string temp;
input >> stu.ID >> stu.firstName >> stu.lastName >> stu.numItems;
int loopnum = stu.numItems;
if (loopnum > 0)
{
for (int i = 0; i < loopnum; i++)
{
input >> temp;
stu.setItem(temp, i);
}
}
return input;
}
ostream & operator<<(ostream & output, const Student & stu)
{
string s = stu.firstName + " " + stu.lastName;
output << setw(8) << stu.ID << setw(16) << s << setw(8) << stu.numItems;
int loopnum = stu.numItems;
if (loopnum > 0)
{
for (int i = 0; i < loopnum; i++)
{
output << stu.items[i] << " ";
}
}
output << endl << endl;
return output;
}
主:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include "student.h"
using namespace std;
void fcheck(ifstream &mystream);
int main()
{
ifstream sin("students.txt"); // File input/output variables
ifstream fin("checkins.txt");
ifstream chin("checkouts.txt");
ofstream sout("UpdatedStudentsC.txt");
Student stu1, stu2;
fcheck(sin);
fcheck(fin);
fcheck(chin);
typedef Student* StuPtr;
StuPtr studentList;
int stud_capacity = 50;
studentList = new Student[stud_capacity];
int num_studs = 0;
sout << std::setiosflags(std::ios::left); // justify output to format properly.
while (sin.good()) // While there's data in the file, do stuff.
{
sin >> stu1;
stu1.CheckIn("Towel");
stu1.CheckIn("Locker");
if (stu1.getnumItems() == 0)
{
stu1.~Student();
}
studentList[num_studs] = stu1;
num_studs++;
sout << stu1;
}
for (int i = 0; i < 16; i++)
{
cout << studentList[i].getID() << " " << studentList[i].getfName() << " " << studentList[i].getnumItems() << endl;
}
system("pause");
// Close files
fin.close();
chin.close();
sout.close();
sin.close();
// Quit without error
return 0;
}
void fcheck(ifstream &mystream)
{
if (!mystream) // If we can't find the input file, quit with error message.
{
cout << "file not opened!" << endl;
system("pause");
exit(1);
}
}
答案 0 :(得分:1)
如果你不告诉它,析构函数会删除任何内容(就像现在一样,你的析构函数是空的)。析构函数用于在释放对象之前执行一些清理,但它不会解除分配。
隐式调用析构函数
delete
解除分配堆对象时。答案 1 :(得分:0)
当任何调用了析构函数的对象都有一个空白的名字和姓氏时,ID和numItems变量仍然存在。
已销毁对象的所有成员变量都不存在。
无法在C ++中检查对象是否已被销毁。当您尝试访问已销毁对象的成员时,该程序将具有未定义的行为。一种可能的行为可能是您可能从被破坏的对象中得到的东西,而另一种可能的行为可能是您没有预料到的。
您调用本地自动变量const test = [
0, 0, 0, 0, 0.0000050048828125, 0.0000137939453125, 0.000049560546875,
0.00008740234375, 0.00015966796875, 0.000262451171875, 0.0003975830078125, 0.0005687255859375,
0.0007802734375, 0.001037353515625, 0.0013468017578125, 0.00172119140625, 0.0021756591796875,
0.0027232666015625, 0.0033880615234375, 0.004206787109375, 0.0052380371093750005,
0.006586181640625, 0.008400146484375001, 0.010904296875, 0.0144892578125, 0.0196798095703125,
0.049684204101562504, 0.0886883544921875, 0.11185363769531251, 0.134164306640625,
0.137352294921875, 0.1160369873046875, 0.08516308593750001, 0.0539765625,
0.014997436523437501, -0.015882568359375, -0.0387554931640625, -0.06125732421875, -0.0745780029296875, -0.07479357910156251, -0.0725338134765625, -0.0418538818359375,
0.08582861328125001, 0.397717529296875, 0.8136408691406251, 1.2295617980957032,
0.9944150390625001, 0.2824605712890625, -0.38949267578125, -0.597251220703125, -0.425675537109375, -0.1537947998046875, -0.0500914306640625, -0.0111041259765625,
0.0027451171875, 0.0071739501953125, 0.008443359375, 0.0094327392578125, 0.012530517578125,
0.0176046142578125, 0.0300162353515625, 0.0433489990234375, 0.056962646484375004,
0.0704832763671875, 0.0770511474609375, 0.0898175048828125, 0.10311853027343751,
0.117046142578125, 0.1312630615234375, 0.1529300537109375, 0.167607177734375,
0.1899068603515625, 0.2124422607421875, 0.235044677734375, 0.2575535888671875,
0.2724073486328125, 0.286978271484375, 0.3007579345703125, 0.3067425537109375,
0.3106370849609375, 0.303756103515625, 0.2897236328125, 0.25916931152343753,
0.2200599365234375, 0.1728209228515625, 0.133416259765625, 0.086224853515625,
0.05493408203125, 0.02409423828125, 0.00922607421875, -0.0043409423828125, -0.0097349853515625, -0.013127685546875, -0.01423095703125, -0.013834716796875, -0.012556030273437501, -0.010675048828125, -0.00835888671875, -0.0057305908203125, -0.0000562744140625
];
//calc the result for Step 1
step1 = test.reduce(function(pre, cur, index, orgArray){
if(cur === 0){pre['found'].push({'type':'no-signal','index':index,'value':0});pre['min']={'value':0,'index':0};pre['max']={'value':0,'index':0};return pre;}
if(pre['max']['value'] < cur) {
pre['max']={'value':cur,'index':index};
if(pre['max']['value']>orgArray[index+1]){pre['found'].push({'type':'upwave','index':index,'value':cur})};
}
if(pre['min']['value'] > cur) {
pre['min']={'value':cur,'index':index};
if(pre['min']['value']<orgArray[index+1]){pre['found'].push({'type':'downwave', 'index':index,'value':cur})};
}
if(orgArray[index-1] > 0 && cur < 0){pre['found'].push({'type':'down-cross','index':index});pre['min']={'value':0,'index':0};pre['max']={'value':0,'index':0};}
if(orgArray[index-1] < 0 && cur > 0){pre['found'].push({'type':'up-cross','index':index});pre['max']={'value':0,'index':0};pre['min']={'value':0,'index':0};}
return pre
},{'max':{'value':0,'index':0}, 'min':{'value':0,'index':0}, 'found':[]})
//console.log(step1['found']);
//Calc the final result
final = step1['found'].reduce(function(pre, cur, index, orgArray){
if(cur.type==='downwave'
&& orgArray[index-1].type==='down-cross'
&& orgArray[index-2].type==='upwave' ) {
pre.push({'type':'S', 'index':cur.index, 'value':cur.value});
}
if(cur.type==='downwave'
&& (index+1 < orgArray.length && orgArray[index+1].type==='up-cross' )
&& (index+1 < orgArray.length && orgArray[index+2].type==='upwave') ) {
pre.push({'type':'Q', 'index':cur.index, 'value':cur.value});
}
if(cur.type==='upwave'
&& orgArray[index-1].type==='up-cross'
&& (index+1 < orgArray.length && orgArray[index+1].type==='down-cross') ) {
pre.push({'type':'R', 'index':cur.index, 'value':cur.value});
}
return pre;
}, []);
console.log(final);
的析构函数,但您没有构建新对象。当变量超出范围时,它将被再次销毁#34;。这也会导致程序具有未定义的行为。需要明确调用析构函数是非常罕见的情况,并非如此。