ArrayList的大小是未知的帮助

时间:2011-06-22 21:07:42

标签: c++ class initialization

我有这段代码

的main.cpp

#include <iostream>
#include "functs.h"

using namespace std;

int main()
{
    ArrayList *al = new ArrayList;
    return 0;
}

functs.h

using namespace std;
#ifndef FUNCTS_H_INCLUDED
#define FUNCTS_H_INCLUDED

class ArrayList;
#endif // FUNCTS_H_INCLUDED

functs.cpp

#include <iostream>
#include "functs.h"

class ArrayList{
    public:
        void add(int num);
        void add(int num, int index);
        void remove(int index);
        void removeNum(int num);
        string toString();
        ArrayList(int init);
    private:
        void resize();
        int size, cap;
        int *myList[10];
};

void ArrayList::add(int num){
    if (size>=cap/2)
    {
        resize();
    }
    *myList[size] = num;
    size++;
}

void ArrayList::resize(){
    int temp[cap*2];
    int i;
    for (i = 0; i < size; i++)
    {
        temp[i] = *myList[i];
    }
    *myList = temp;
}

ArrayList::ArrayList(){
    size = 0;
    cap = 10;
}

void ArrayList::add(int num, int index){
    int temp = *myList[index];
    int i;
    for (i = index; i < size; i++)
    {
        *myList[index] = num;
        num = temp;
        temp = *myList[i+1];
    }
    add(temp);
}

string ArrayList::toString(){
    string returnString = "{";
    int i;
    for (i = 0; i < size; i++)
        returnString.append(*myList[i] +",");
    returnString.replace(returnString.length()-1,1,"}");
    return returnString;
}

我对C ++非常陌生,但每当我尝试编译代码时,它都会给我一个“不知道ArrayList的大小”。请帮我弄清楚错误。 =(

4 个答案:

答案 0 :(得分:6)

尽管您的代码中存在设计/使用问题,但最明显的问题是您希望将类定义放在functs.h文件而不是functs.cpp文件中:

functs.h

// This is declaration is highly not recommended for use in header files.
// using namespace std;

#ifndef FUNCTS_H_INCLUDED
#define FUNCTS_H_INCLUDED

#include <string>

class ArrayList{
    public:
        void add(int num);
        void add(int num, int index);
        void remove(int index);
        void removeNum(int num);
        std::string toString();
        ArrayList(int init);
    private:
        void resize();
        int size, cap;
        int *myList[10];
};

#endif // FUNCTS_H_INCLUDED

functs.cpp

#include "functs.h"

void ArrayList::add(int num){
    if (size>=cap/2)
    {
        resize();
    }
    *myList[size] = num;
    size++;
}

void ArrayList::resize(){
    int temp[cap*2];
    int i;
    for (i = 0; i < size; i++)
    {
        temp[i] = *myList[i];
    }
    *myList = temp;
}

ArrayList::ArrayList(){
    size = 0;
    cap = 10;
}

void ArrayList::add(int num, int index){
    int temp = *myList[index];
    int i;
    for (i = index; i < size; i++)
    {
        *myList[index] = num;
        num = temp;
        temp = *myList[i+1];
    }
    add(temp);
}

std::string ArrayList::toString(){
    std::string returnString = "{";
    int i;
    for (i = 0; i < size; i++)
        returnString.append(*myList[i] +",");
    returnString.replace(returnString.length()-1,1,"}");
    return returnString;
}

templatetypedef提供了必要的原因。基本上,编译器需要知道ArrayList需要多少空间,class ArrayList;不提供此类信息。


在头文件中声明using namespace std;并不是一个好主意,因为包含functs.h文件的所有人(包括您的客户端!)也会有一个using namespace std;,从而增加名称冲突的可能性。


如果您希望正确学习C ++,我强烈建议您选择a good introductory C++ book。你在你的问题中证明了对C ++编写得有多好的误解。这并不是说你作为一个人不称职,但你提出的代码存在一些严重的问题。仅举几例:

  • 标准C ++已经提供了一个名为std::vector的完美的数组类。没有必要为你正在做的事情重新发明轮子。即使您必须重新发明轮子,对C ++和大量C ++经验的深入理解也是实现适合生产使用的阵列容器的先决条件。
  • 您班级的公共界面不完整。客户无法知道数组中实际有多少元素。
  • int *myList[10];声明一个包含10个指向int固定数组。这不适用于数组类。特别是如果你想让数组可以调整大小。
  • 这个类没有足够的内存管理在任何意义上都有用。没有析构函数,显然构造函数不完整(也不匹配),所以你没有真正的逻辑位置来放置new[]delete[]之类的东西。
  • 您有ArrayList *al = new ArrayList;,但在任何地方都没有相应的delete al;。这是内存泄漏。
  • 但最后一点是没有意义的,因为你应该使用ArrayList a1;代替ArrayList *al = new ArrayList;。前者将在范围的末尾自动“删除”自身(在本例中为main()函数),而后者需要delete语句。 C ++与Java不同,自动收集未使用的new'ed对象。

我不能对你使用的算法的正确性发表评论,因为(而且我很遗憾地说这是因为它听起来很苛刻)你所拥有的算法根本不起作用。我再次建议你选择a good introductory C++ book,这将涵盖这些问题。 (我必须强调,这些缺点都不是你作为一个人的陈述。我正在谈论你在问题中的代码。)

答案 1 :(得分:2)

您收到此错误的原因是在main.cpp中,编译器没有看到类ArrayList的定义。它只能看到声明

class ArrayList;

当您尝试通过编写

创建ArrayList
new ArrayList;

编译器不知道保存ArrayList需要多少内存,因为它没有看到类定义。这与Java之类的其他语言形成鲜明对比,在这些语言中,这些信息不必立即可用。

要解决此问题,请通过从.h文件移动类的定义来更新.cpp文件。这样,当某人#include成为头文件时,除了声明之外,他们还会获得定义类,这将允许您使用{{ 1}},声明类型为new等的局部变量

希望这有帮助!

答案 2 :(得分:0)

这么多

class ArrayList{
    public:
        void add(int num);
        void add(int num, int index);
        void remove(int index);
        void removeNum(int num);
        string toString();
        ArrayList(int init);
    private:
        void resize();
        int size, cap;
        int *myList[10];
};

应该在.h文件中。

为什么呢?因为类的声明(当你编写class ArrayList;时)仅在不需要类的大小时才足够(更具体的情况在C ++标准中列出)。该类的定义应出现在同一个翻译单元中,在该翻译单元中,该类的使用方式需要完整。

答案 3 :(得分:0)

你声明myList的方式有一个固定的大小; *myList = temp;没有按你的意愿行事。

将myList简单地声明为int * myList;

在构造函数中,使用myList = new int[10];

您将*myList[...]改为myList[...]

在调整大小时,int temp[cap*2]必须为int *temp = new int[cap * 2]*myList = temp必须为myList = temp

你仍然会有内存泄漏,但这应该让你开始。