我创建了一个包含动态数组的类 Student。我已经用构造函数填充了前两个项目。我尝试用来从主元素访问/打印这两个元素的每种方法都会发生读取/访问冲突并崩溃。我在构造函数中添加了一个 cout,显示元素已填充并存在。我在 main 中包含两个失败的方法:一个尝试将第一个元素发送到 cout 的 void 函数,以及一个接受所需索引的 int 的方法。两者都已被注释掉,以允许测试运行显示元素由构造函数创建和打印。
页眉:
#ifndef STUDENT_H
#define STUDENT_H
#include <string>
#include <iostream>
#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;
Student();
Student(const string fName, const string lName, const unsigned int id);
string getfName() const;
string getlName() const;
void getItem(int num);
string getItemB(int num) const;
unsigned int getID() const;
};
#endif // STUDENT_H
定义:
#include "student.h"
using namespace std;
Student::Student()
{
}
Student::Student(const string fName, const string lName, const unsigned int id)
{
firstName = fName;
lastName = lName;
ID = id;
StringPtr items = new string[capacity];
numItems = 0;
items[0] = "stuff";
items[1] = "things";
cout << items[0] << endl << items[1] << endl;
}
string Student::getfName() const
{
return firstName;
}
string Student::getlName() const
{
return lastName;
}
void Student::getItem(int num)
{
cout << items[0] << endl;
}
string Student::getItemB(int num) const
{
return items[num];
}
unsigned int Student::getID() const
{
return ID;
}
主要:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "student.h"
using namespace std;
int main()
{
Student stu;
string str;
stu = Student("John", "Smith", 1200);
cout << stu.getfName() << " " << stu.getlName() << endl;
//stu.getItem(0);
//cout << stu.getItemB(0);
system("pause");
// Quit without error
return 0;
}
解决方案
改变
StringPtr items = new string[capacity];
到
items = new string[capacity];
TL;博士
在
Student::Student(const string fName, const string lName, const unsigned int id)
{
firstName = fName;
lastName = lName;
ID = id;
StringPtr items = new string[capacity];
numItems = 0;
items[0] = "stuff";
items[1] = "things";
cout << items[0] << endl << items[1] << endl;
}
该行
StringPtr items = new string[capacity];
创建一个新的自动(局部)变量items
并初始化它,而不是预期的private
成员变量StringPtr items;
。这通常称为可变阴影。本地items
在函数结束时超出范围,泄漏分配的内存,并且成员items
从未初始化,导致stu.getItem(0);
访问未初始化的指针并触发崩溃。
void Student::getItem(int num)
{
cout << items[0] << endl; // items points Crom knows where, so items[0] is invalid.
}
这次崩溃是相当幸运的。访问一个单位化的指针会导致未定义的行为,这意味着它可以做任何事情,从看起来有效到导致宇宙爆炸。
你必须处理的下一个问题是遵守三法则。
处理这个问题的最好方法是std::vector
std::vector<string> items;
std::vector
符合三法则(实际上是五法则),因此您不必这样做。
如果不允许std::vector
,则需要实现复制构造函数
Student::Student(const Student & src):
firstName(src.firstName), lastName(src.lastName),
ID(src.ID), numItems(src.numItems),
items(new string[capacity])
{
for (int i = 0; i < src.numItems; i++)
{
items[i] = src.items[i];
}
}
和赋值运算符(为简单起见,利用复制和交换习惯用法)
Student & Student::operator=(Student src)
{
swap(*this,src);
return *this;
}
写swap
我就交给你了。