C++类成员变量中的数组

6

我可以像下面这样在C++中使用数组作为类的成员变量吗?还是应该将其声明为指针?以下代码可以正常工作,这样做正确吗?(我只是为了简单起见将其公开)。我也不确定自己是否正在正确地使用map。

#include <iostream>
#include <map>
#include <string.h>

using namespace std;

class SimpleMap{
public:
    map<string,int> m;
    int i;
    int j[];
    SimpleMap(int ii);
};

SimpleMap::SimpleMap(int ii){
    i = ii;
}



int main(){
    SimpleMap mm(5);
    mm.m["one"] = 1;

    cout<<"hi hru";

    cout<<mm.m["one"];

    mm.j[0] = 11;
    cout << mm.j[0];
}

编辑:我已经添加了地图成员变量。


1
你确定那个能正常工作吗?它不应该这样。 - Tom van der Woerdt
1
“表面工作”和“实际工作”是有区别的。仅仅因为没有明显的崩溃或其他问题,并不意味着程序正在合理地运行。 - Nicol Bolas
头文件 string.h 已经被弃用。如果你确实需要 C 字符串操作 API,请使用 cstring。但是无论如何,你应该优先选择 string - pmr
4个回答

7

实际上,你已经有一个指针了。但是它没有初始化。

在某些情况下,设置 j[0] 是可行的,但是你会写入未分配的内存,或者更糟糕的是,写入另一个对象使用的内存。基本上,你正在创建一个巨大的漏洞。

考虑使用 std::vector,它只需为你执行所有的内存分配/释放操作。如果这不是一个选择,至少要初始化数组,并且不要超出你所分配的范围。

j[] 只是指向随机内存地址的指针 *j。非常、非常、非常糟糕。


请问一下,我是否正确地使用了map函数? - FourOfAKind
你很棒。使用 std 对象创建内存泄漏非常困难。 :-) - Tom van der Woerdt
@Tom: ; new std::vector<double>(500);。这很简单!>> ... <_< ... >> - Xeo
@Xeo 嗯,谁会像那样使用向量呢?而且,好的编译器会对此发出警告。 - Tom van der Woerdt
@Tom:这只是对你“非常难”的玩笑回答。 :) - Xeo
@Xeo:哦 :-) 在这些评论框中,幽默非常难(你看我做了什么?)。 - Tom van der Woerdt

3
int j[];

这并不是你想象的那样,它实际上定义了一个指针:int* j;,它没有被初始化,在未初始化状态下读取它是未定义行为,也就是说是错误的。

只需使用std::vector即可。


我其实很困惑如何将这些复合数据结构用作类的数据成员。我发布了另一个使用映射作为数据成员的代码片段。请看一下我是否做错了,那段代码是否也能正常工作。 - FourOfAKind
为什么将类成员声明放在函数体中(无论是自由函数还是成员函数)会出错,但将其放在类成员中却可以编译通过? - jrok
@Jrok:你能详细说明一下吗? - FourOfAKind
@Lamia:你现在使用的地图很好,但是以后仅使用operator[]可能不够。 :) 请熟悉map.find - Xeo
@Xeo 如果作者写成了 int j[3];,那么 j 仍然是一个指针吗? - interestedparty333
这不是正确的。如果支持,这是一个变量数组成员,而不是指针。 - Flamefire

0

不,我认为int j[];是在声明时初始化数组时使用的。您应该为数组提供一个上限。我认为这样是正确的:int j[]={3,2,1};


很遗憾,在类定义内部无法这样做。 - Xeo
@Tom:如果你有一个int j[]成员,尤其是那种语法,就不行。 - Xeo

0

我在谷歌上发现了一个混淆的答案,想在这里澄清一下:在结构体中使用T name[]作为最后一个成员被称为“灵活数组成员”,并由例如GCC和Clang等编译器定义为C语言的扩展。以下是一个示例用法:

struct Array{
  int len;
  float ar[];
};
// Create
Array* foo = malloc(sizeof(Array) + 100 * sizeof(float));
foo.len = 100;
// Use
for(int i=0; i<foo.len; i++) foo.ar[i] = i * M_PI;

特殊成员实际上不是成员,而是一些编译器魔法,类似于struct Array{ int len; float ar[100]; };但您可以在运行时选择大小。

然而,在C++中使用这个要困难得多,因为您需要考虑对象的生命周期。所以不要在C++中直接使用此方法

对于OP的情况:您可能想要一个真正的指针,并且需要为指向的数组分配空间。显然,如已经指出的那样,std::vector解决了大部分问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接