为什么 cocos 2d-x v3 在 C++ 中如此频繁地使用指针?
why does cocos 2d-x v3 use pointers so often in c++?
我是来自 Java 的 c++ 程序员新手,我喜欢 c++。据我所知,我认为指针通常指向已经初始化的对象的地址。在 coocos2d 中,通常为了创建一个对象,您会按照以下行编写一些内容:
auto mysprite=Sprite::create("image.png");
并为 mysprite 使用一个方法,你会这样写:
mysprite->mymethod();
我对指针的基本了解是它们的用法如下:
int* mypoint;
int x=7;
mypoint=&x;
来自 java 这很令人困惑为什么你不会或什么时候会创建一个像这样调用 class 本身的对象:
Sprite* mysprite=Sprite::create("image.png");
mysprite.mymethod();
我认为完全理解这一点很重要,因为 cocos2d 库中的许多构造函数都在构造函数中使用指针,我发现自己盲目地将 auto 写为变量的标识符,但我不确定为什么.感谢您提前澄清。
my question is why would i use "->" instead of "."
因为左边的东西是指针
如果 a
是指针,则 a->b
与 (*a).b
相同,只是看起来更好。
如果 a
是一个指针,那么 a.b
是一个错误。
在 C++ 中,指针占据的位置与 Java 中的对象引用(又名对象)大致相同。在 Java 中,您可以执行以下操作:
String foo = new String;
当您执行此操作时,foo
实际上是引擎盖下的指针。例如,您可以这样做:
String foo = new String;
String bar = foo;
并且这不会创建 String
的副本,它只是将 bar
设置为引用与 foo 相同的 String
。对于 String
这不是一个重要的区别,因为 Java 中的 String
类型是不可变的。但是,对于这样的事情:
int[][] foo = new int[5][5];
int[][] bar = foo;
bar[0][0] = 6;
那就重要了。当你设置 bar[0][0]
时你也设置了 foo[0][0]
因为它们指的是同一个数组。 bar
和 foo
是对某物的引用,而不是值。在 Java 中,这有点模糊,因为您唯一可以拥有的值是原始类型,例如 int
或 float
.
在 C++ 中,您可以拥有复杂类型的值。例如,如果您这样说:
struct point_2d {
int x, y;
};
void a_function()
{
point_2d p1;
point_2d p2 = p1;
p2.x = 5;
}
首先,请注意 new
的缺失。在 C++ 中,new
用于创建事物 'on the heap',这是 Java 放置 一切 非原始类型的地方。在 C++ 中,p1
和 p2
与 Java 放在 int x;
和 int y;
的位置相同。在堆栈上。它们在函数退出时被销毁,并不是因为对它们的所有引用都消失了所以它们被垃圾收集了。他们不顾一切地离开了。
此外,当您执行 p2.x = 5;
时,p1.x
的值没有改变。当您创建 p2
时,您从 p1
复制了值。您没有创建对它的另一个引用。所以这些值是相互独立存在的。
现在,为什么您的图书馆到处乱扔指针?好吧,C++ 中的指针就像 Java 引用(换句话说,Java 中的每个变量都不是原始类型)。但是,由于 C++ 中的默认值不是引用(与 Java 不同),因此您必须明确说明何时有,何时没有。
在您的特定情况下,库在 Sprite::create
函数内部的某处正在执行类似 Sprite *newsprite = new Sprite;
的操作。所以,它在堆上创建了一个 Sprite
。很可能,它实际上是从 Sprite
派生的 class 而不是 Sprite
本身,而是相同的基本思想。
您一直不得不使用 ->
而不是 .
,因为 ->
用于通过指针访问 class 的成员,而 .
用于通过值访问它们。由于 Java 没有那种区别(任何你会使用 .
的东西已经是一个指针)它没有两种不同的语法。
这意味着您必须在某个时间点执行 delete mysprite;
以释放它正在使用的内存。与 Java 不同,C++ 不会为您进行内存管理(也称为垃圾回收)。
您正在使用的这个 cocos 2d-x v3 库似乎也有一个相当老式的界面。在现代 C++ 中,出于各种不同的原因,不鼓励使用裸指针。该库应该返回 ::std::shared_ptr<Sprite>
或 ::std::unique_ptr<Sprite>
。但这超出了这个问题的范围。
但是,库确实必须使用指针。 Sprite
的复制成本可能相当高(特别是因为该库似乎使用的是较旧的界面风格,因此可能没有利用诸如移动构造函数之类的漂亮功能),因此该库希望在堆并传递给你一个参考(又名指针),因为它们复制起来很便宜。
此外,在您了解发生了什么之前,请尽量不要使用 auto
。 C++ 的自动类型推导在各种情况下都非常好,尤其是在使用容器 classes 时,有时迭代器等的类型名称可能非常复杂。但它允许您使用类型而无需真正知道您使用的是哪些类型。就您而言,就您的经验水平而言,您尝试使用的库并不是很好。
这个主题对于 Whosebug 的回答来说实在是太复杂了。但这是正在发生的事情的基础,应该提供
我是来自 Java 的 c++ 程序员新手,我喜欢 c++。据我所知,我认为指针通常指向已经初始化的对象的地址。在 coocos2d 中,通常为了创建一个对象,您会按照以下行编写一些内容:
auto mysprite=Sprite::create("image.png");
并为 mysprite 使用一个方法,你会这样写:
mysprite->mymethod();
我对指针的基本了解是它们的用法如下:
int* mypoint;
int x=7;
mypoint=&x;
来自 java 这很令人困惑为什么你不会或什么时候会创建一个像这样调用 class 本身的对象:
Sprite* mysprite=Sprite::create("image.png");
mysprite.mymethod();
我认为完全理解这一点很重要,因为 cocos2d 库中的许多构造函数都在构造函数中使用指针,我发现自己盲目地将 auto 写为变量的标识符,但我不确定为什么.感谢您提前澄清。
my question is why would i use "->" instead of "."
因为左边的东西是指针
如果 a
是指针,则 a->b
与 (*a).b
相同,只是看起来更好。
如果 a
是一个指针,那么 a.b
是一个错误。
在 C++ 中,指针占据的位置与 Java 中的对象引用(又名对象)大致相同。在 Java 中,您可以执行以下操作:
String foo = new String;
当您执行此操作时,foo
实际上是引擎盖下的指针。例如,您可以这样做:
String foo = new String;
String bar = foo;
并且这不会创建 String
的副本,它只是将 bar
设置为引用与 foo 相同的 String
。对于 String
这不是一个重要的区别,因为 Java 中的 String
类型是不可变的。但是,对于这样的事情:
int[][] foo = new int[5][5];
int[][] bar = foo;
bar[0][0] = 6;
那就重要了。当你设置 bar[0][0]
时你也设置了 foo[0][0]
因为它们指的是同一个数组。 bar
和 foo
是对某物的引用,而不是值。在 Java 中,这有点模糊,因为您唯一可以拥有的值是原始类型,例如 int
或 float
.
在 C++ 中,您可以拥有复杂类型的值。例如,如果您这样说:
struct point_2d {
int x, y;
};
void a_function()
{
point_2d p1;
point_2d p2 = p1;
p2.x = 5;
}
首先,请注意 new
的缺失。在 C++ 中,new
用于创建事物 'on the heap',这是 Java 放置 一切 非原始类型的地方。在 C++ 中,p1
和 p2
与 Java 放在 int x;
和 int y;
的位置相同。在堆栈上。它们在函数退出时被销毁,并不是因为对它们的所有引用都消失了所以它们被垃圾收集了。他们不顾一切地离开了。
此外,当您执行 p2.x = 5;
时,p1.x
的值没有改变。当您创建 p2
时,您从 p1
复制了值。您没有创建对它的另一个引用。所以这些值是相互独立存在的。
现在,为什么您的图书馆到处乱扔指针?好吧,C++ 中的指针就像 Java 引用(换句话说,Java 中的每个变量都不是原始类型)。但是,由于 C++ 中的默认值不是引用(与 Java 不同),因此您必须明确说明何时有,何时没有。
在您的特定情况下,库在 Sprite::create
函数内部的某处正在执行类似 Sprite *newsprite = new Sprite;
的操作。所以,它在堆上创建了一个 Sprite
。很可能,它实际上是从 Sprite
派生的 class 而不是 Sprite
本身,而是相同的基本思想。
您一直不得不使用 ->
而不是 .
,因为 ->
用于通过指针访问 class 的成员,而 .
用于通过值访问它们。由于 Java 没有那种区别(任何你会使用 .
的东西已经是一个指针)它没有两种不同的语法。
这意味着您必须在某个时间点执行 delete mysprite;
以释放它正在使用的内存。与 Java 不同,C++ 不会为您进行内存管理(也称为垃圾回收)。
您正在使用的这个 cocos 2d-x v3 库似乎也有一个相当老式的界面。在现代 C++ 中,出于各种不同的原因,不鼓励使用裸指针。该库应该返回 ::std::shared_ptr<Sprite>
或 ::std::unique_ptr<Sprite>
。但这超出了这个问题的范围。
但是,库确实必须使用指针。 Sprite
的复制成本可能相当高(特别是因为该库似乎使用的是较旧的界面风格,因此可能没有利用诸如移动构造函数之类的漂亮功能),因此该库希望在堆并传递给你一个参考(又名指针),因为它们复制起来很便宜。
此外,在您了解发生了什么之前,请尽量不要使用 auto
。 C++ 的自动类型推导在各种情况下都非常好,尤其是在使用容器 classes 时,有时迭代器等的类型名称可能非常复杂。但它允许您使用类型而无需真正知道您使用的是哪些类型。就您而言,就您的经验水平而言,您尝试使用的库并不是很好。
这个主题对于 Whosebug 的回答来说实在是太复杂了。但这是正在发生的事情的基础,应该提供