这个大学的学期我有一个名为Data Structures的课程,教授允许学生选择他们喜欢的语言。因为我想成为一名游戏程序员,而且我不能再使用Java了,所以我选择了C ++ ......但是现在我因为缺乏这种语言的知识而陷入困境。我必须做以下事情:创建一个SuperArray,它就像一个Delphi数组(你可以选择它的起始和结束索引)。我的代码如下:
的main.cpp
#include <iostream>
#include "SuperArray.h"
using namespace std;
int main(int argc, char** argv)
{
int start, end;
cout << "Starting index" << endl;
cin >> start;
cout << "Ending index:" << endl;
cin >> end;
SuperArray array = new SuperArray(start,end);
}
superarray.h
#ifndef _SUPERARRAY_H
#define _SUPERARRAY_H
class SuperArray
{
public:
SuperArray(int start, int end);
void add(int index,int value);
int get(int index);
int getLength();
private:
int start, end, length;
int *array;
};
#endif /* _SUPERARRAY_H */
superarray.cpp
#include "SuperArray.h"
SuperArray::SuperArray(int start, int end)
{
if(start < end)
{
this->start = start;
this->end = end;
this->length = (end - start) + 1;
this->array = new int[this->length];
}
}
void SuperArray::add(int index, int value)
{
this->array[index-this->start] = value;
}
int SuperArray::get(int index)
{
return this->array[index-this->start];
}
当我尝试编译此代码时,出现以下错误:
error: conversion from `SuperArray*' to non-scalar type `SuperArray' requested
我该怎么办?
答案 0 :(得分:6)
与Java不同,在C ++中,您不需要 来使用new
关键字来创建对象。在Java中,所有对象都存储在堆(免费存储)中,并且只能通过引用访问。
在C ++中,对象可以是值类型。您可以直接在堆栈上声明它们,例如
SuperArray array(start, end);
您可以调用以下方法:
array.get(1);
当array
超出范围时,此对象将自动销毁。如果要手动管理array
对象的生命周期,可以选择使用new
在堆上创建它,但是你必须用指针引用它:
SuperArray* array = new SuperArray(start, end);
现在,你必须调用这样的方法:
array->get(i);
因为在这种情况下array
是指向SuperArray
而不是SuperArray
本身(并且指针本身没有get
方法)的指针。 ->
运算符表示在指向对象上使用.
运算符。
在这种情况下,array
指针指向的对象将继续存在,直到您调用delete array;
如果未能显式删除该对象,它将永远不会被释放(C ++没有垃圾收藏家!)你会有内存泄漏。
请注意,C ++有称为“指针”的东西和称为“引用”的东西。 Java“引用”具有这两者的一些属性,并不直接等同于任何一种。关于C ++的一个很好的介绍性文本应该解释它们之间的区别。
答案 1 :(得分:1)
array
应该是要在堆上分配的指针。将其定义更改为:
SuperArray* array = new SuperArray(start,end);
您可以通过在本地堆栈上分配数组来删除指针:
SuperArray array(start,end);
如果您不打算跨模块传递共享对象,则堆栈对象就足够了。
答案 2 :(得分:1)
至少作为一个起点(并且可能是永久性的,除非教授让我改变它)我会使用std::vector
来管理存储,并且只写一个管理偏移的前端到索引根据需要。
编辑:如果我被迫改变它,我仍然会研究std::vector
的界面,并尽可能地模仿它,所以几乎唯一的变化就是(可能)非零更低绑定在索引上。我还将研究它如何管理记忆,并模仿它。最后,我将以相同的方式对事物进行分段 - 即,有一个类只管理一个固定下限为零的向量,另一个类只处理非零下限所需的索引的偏移量界。