我从c#来到c ++,我不明白动态对象是什么。所以想象你有A类并且创建对象如A * a = new A()是Normal但是对象是什么?像阵列一样是什么?我们可以像[0]或[1]那样写吗?但是,如果我们重载operator []并想要创建动态对象,如果我们在那里有数据并且想要正常获取数据,会发生什么?
答案 0 :(得分:6)
指针只是听起来像是什么,它是指向其他地方的东西。
举个例子
A* a = new A;
将变量a
声明为指针。它指向A
类的实例(对象)。
有点图形化,可以看作是
+---+ +---------------+ | a | ---> | instance of A | +---+ +---------------+
在C#(和Java)中,这基本上是创建类实例的唯一方法。所有变量都是(略微简化)指针。
在C ++中,您还有其他选择:
A a;
上面的定义表明变量a
是 A
类的一个实例。它不是引用,它不是指针, 是A
对象。
现在,上述两个定义之间存在另一个差异:在第一种情况下,{em>运行时创建了A
的实例。程序运行时为实例分配内存。在第二种情况下,实例的空间在编译时由编译器分配。但是在这两种情况下都会在运行时调用构造函数。
答案 1 :(得分:3)
如果编写A * a = new A()
,则调用类A
的默认构造函数,并为类A
的一个对象动态分配内存,并将分配的内存地址分配给指针a
。所以a
指向类A
的对象而不是数组。但是,如果您想动态生成A
个对象数组,那么您必须编写类似A * a = new A[10]
的内容。这将分配10个A
对象的内存。您可以编写a[0], a[1], ... a[9]
来访问数组的对象。
现在,如果我们重载[]
运算符会发生什么?如果我们重载[]
运算符,那么它应该意味着类A
内部有某种数组,并且通过编写a[1]
,其中a
是类的对象{ {1}},我们希望将元素放在第二个索引处。 (一般来说,你可以使用下标运算符来表示其他任何东西,但你应该尝试坚持下标运算符的原始含义)。但我们不能在指针上调用A
运算符,因为它意味着取消引用指针。因此,要在对象的指针上调用下标运算符,我们必须显式调用下标运算符。像这样:
[]
它创建了一个类A * a = new A;
cout << a->operator[](0) << endl;
的一个对象,并编写了A
。它显式调用重载的下标运算符。如果我们动态创建一个数组怎么办?
a->operator[](0)
第一个下标运算符用于获取对象数组中的第一个对象。第二个下标运算符正在调用对象A * a = new A[6];
cout << a[0][0] << endl;
答案 2 :(得分:0)
'a'是指向对象'A'的内存的指针(内存地址)。它的行为就像一个数组。但是你只有一个元素,所以'a [0]'相当于'* a'。在你的情况下不要尝试[1]。它会编译,但很可能在运行时崩溃。如果你超载[],现在是你的问题:-)。虽然你不能在指针上重载[]。
顺便说一下,在c#'a'中也是对象的指针(引用),而不是对象本身。语言之间最大的区别是c ++ 不管理内存分配。因此,如果您说“新”,请确保在您不再需要该对象时也说“删除”。
在'c +'中你也可以创建引用而不是指针。