数组随机访问 C++

Array Random Access C++

我可能会在写这篇文章时把自己搞糊涂了,提前道歉:

有没有一种方法可以使用 sizeof() 数组中的对象访问指针的动态数组(递增数组指针)中的位置?

例如: 我有一个类型为 base class Student 的动态数组,其中填充了派生的 class 对象(研究生、本科生)。

由于这个原因,我无法以正常方式逐步遍历我的数组来显示信息,因为实际对象 Graduate 和 Undergraduate 的大小与 Student 不同。当实际对象较大时,每个阵列步骤将移动 sizeof(Student)

取决于我正在做的学生类型(这是针对研究生的):

Student *student = new Graduate(undergrad, fName, lName, major, idNum, arr2, cSize, 
        degreeType, thesis);
arr[i] = student;

声明 arr 的位置:Student *arr = new Student[size];

使用我的数组,我在 for 循环中创建了这个:

if (!students[i].getGradStatus()){
    handleGraduate(&students[i], i);
    step = step + sizeof(Graduate);
}
else if (students[i].getGradStatus()){
    handleUndergraduate(&students[i], i);
    step = step + sizeof(Undergraduate);
}

我试图想出一种改变步长的方法。我认为这不适用于 for 循环,但 while 循环可能会有所不同。几乎我正在尝试执行类似于文件 seekg() 的操作,但手动在数组上进行。

而且我注意到每个人都喜欢质疑使用动态数组而不是向量所以我只想说我不能在这个项目上使用向量(不允许使用 STL :( )。而且我必须使用多态性,这就是为什么我有一个 Student 类型的数组指针,其中包含派生的 class 个对象。

将您的数组更改为 Student 指针数组而不是 Student 对象。

 Student **arr = new Student*[size];

当您这样做时,您的对象将存在于堆中并且指针大小始终相同,因此您遇到的问题就会消失。

既然你可以这么写,我假设可以实例化一个 Student(非派生的)。这很糟糕,因为您要将派生对象存储在数组中,您的学生将被切片(可怜的学生!)。为了反驳你正在用实例类型的大小做一些奇怪的事情。只是不要。

创建一个学生指针数组,Student **arr。指针具有固定大小,它们将指向任何派生类型的学生,因此您不必担心它们的大小。


Student **student = new Student*[size];
...
student[i] = new Graduate(...);

这应该有效。

您不能像那样在数组中存储不同大小的对象。当您尝试将 派生类型 复制到 Graduate 之类的 基本类型 (例如 Student 时,您会得到所谓的 切片 因为对象大小不同(部分可能会被切掉)。

为此,您需要存储 Student*(指向 Students 的指针)

class Student
{
    std::string name;
public:
    Student(const std::string& name): name(name) {}
    virtual ~Student() {} // virtual destructor

    virtual void handle() = 0; // implementation must override this

    std::string get_name() const { return name; }
};

class Graduate
: public Student
{
public:
    Graduate(const std::string& name): Student(name) {}
    virtual void handle() { std::cout << "Handling Graduate" << '\n'; }
};

class UnderGraduate
: public Student
{
public:
    UnderGraduate(const std::string& name): Student(name) {}
    virtual void handle() { std::cout << "Handling UnderGraduate" << '\n'; }
};

int main()
{
    Student** students = new Student*[3];

    students[0] = new Graduate("Wendy");
    students[1] = new UnderGraduate("Bob");
    students[2] = new Graduate("Rachel");

    for(int i = 0; i < 3; ++i)
    {
        std::cout << students[i]->get_name() << '\n';
        students[i]->handle(); // polymorphic function (virtual)
    }

    delete[] students; // clean up or (better) use a smart pointer
}

输出:

Wendy
Handling Graduate
Bob
Handling UnderGraduate
Rachel
Handling Graduate