与C中的对象数组混淆

与C中的对象数组混淆,第1张

概述所以我首先学习了 Java,现在我试图切换到C.让数组正常工作有点困难. 现在我只是试图创建一个对象“Player”的数组,并用一个填充它.但是我收到一个错误. Player* players = new Player[1];players[0] = new Player(playerWidth, playerHeight, 20, 1); 错误说: *** 作数“=”匹配这些 *** 作数. *** 作数类型为:P 所以我首先学习了 Java,现在我试图切换到C.让数组正常工作有点困难.

现在我只是试图创建一个对象“Player”的数组,并用一个填充它.但是我收到一个错误.

Player* players = new Player[1];players[0] = new Player(playerWIDth,playerHeight,20,1);

错误说:
*** 作数“=”匹配这些 *** 作数. *** 作数类型为:Player = Player *

我不明白为什么这不工作?

解决方法 错误是说您正在尝试为变量分配一个错误类型的值.当错误说Player = Player *时,表示左侧的变量是Player,右侧的值是Player *.
players[0] = new Player(playerWIDth,1);

问题类似于你要做的事情:

int x;x = "Hello,World!";

左手和右手类型不匹配,并且没有自然转换,因此您会收到错误.

第一个问题是您来自Java背景,Java使用指针很多但是隐藏了它们. C根本不隐藏它们.结果是C具有不同的语法来明确处理指针. Java摆脱了所有这些,大多数使用C的常规非指针语法来处理指针.

Java:                                  C++:Player player = new Player();          Player *player = new Player();Player player2;                        Player *player2 = nullptr;** no equivalent in java **            Player player3;player.foo();                          player->foo();** no equivalent in java **            player3.foo();** no equivalent in java **            *player;** no equivalent in java **            &player2;

了解使用指针并直接与对象进行工作的区别非常重要:

Java:                                  C++:Player a = new Player();               Player *a = new Player();Player b = a;                          Player *b = a;b.foo();                               b->foo();

在这段代码中,只有一个对象,你可以通过a或b访问它,并没有什么区别,a和b都是同一个对象的指针.

C++:Player c = Player();Player d = c;d.foo();

在这段代码中有两个对象.他们是独特的,做某事不影响c.

如果在Java中,您了解到像“String”这样的“primitive”类型之间的区别,那么一个想法就是在C中所有对象都是原始的.如果我们回顾你的代码,并使用这个’C对象就像Java原语’规则,你可能会看到更好的是什么问题:

Java:int[] players = new int[1];players[0] = new int(playerWIDth); // huh???

这应该清楚,任务的右侧应该只是一个Player值,而不是一个新的玩家对象的动态分配.对于java中的int来说,这看起来像玩家[0] = 100;由于Java中的对象类型不同Java没有办法通过写入int值的方式写入Object值.但是C呢player [0] = Player(playerWIDth,1);

第二个问题是C中的数组是奇怪的,C继承.

C和C中的指针允许“指针算术.如果您有一个指向对象的指针,您可以添加或减少对象,并获取指向其他对象的指针. Java没有什么类似的.

int x[2]; // create an array of two ints,the ints are 'adjacent' to one another// if you take the address for the first one and 'increment' it// then you'll have a pointer to the second one.int *i = &x[0]; // i is a pointer to the first elementint *j = &x[1]; // j is a pointer to the second element// i + 1 equals j// i equals j - 1

另外,数组索引运算符[]适用于指针. x [5]等价于*(x 5).这意味着指针可以用作数组,这在C和C中是惯用的和预期的.其实它甚至被烤成了C.

在C中,当您使用新的动态分配对象,例如新玩家,你通常会得到一个指向你指定的类型的指针.在此示例中,您将获得Player *.但是当您动态分配数组时,例如新玩家[5],这是不同的.而不是返回一个指向五个玩家数组的指针,您实际上会获得一个指向第一个元素的指针.这就像任何其他玩家*:

Player *p   = new Player;    // not an arrayPlayer *arr = new Player[5]; // an array

唯一使这个指针不同的是当你对它进行指针运算时,你会获得指向有效的Player对象的指针:

Player *x = p + 1;   // not pointing at a valID PlayerPlayer *y = arr + 3; // pointing at the fourth array element

如果您在没有保护的情况下使用它们,则新建和删除将很难正确使用为了证明这一点:

int *x = new int;foo();delete x;

此代码容易出错,可能是错误的.具体来说,如果foo()抛出一个异常,那么x被泄漏.

在C任何时候,如果你收到一个责任,比如当你打电话给你时,你会收到以后调用delete的责任,你应该记住

R.A.I.I.
Responsibility* Acquisition Is Initialization

更多的人说“资源获取是初始化”,但资源只是一种责任.在他的Exception Safe C++次谈判中,我被劝说使用后者Jon Kalb.

R.A.I.I.意味着每当你获得责任时,它应该看起来像你正在初始化一个对象;具体来说,您正在初始化一个特殊对象,其目的是为您管理该责任.这种类型的一个例子是std :: unique_ptr< int>它将管理分配给new的int指针:

C++:std::unique_ptr<int> x(new int);foo();// no 'delete x;'

要管理你的Player数组,你可以使用std :: unqiue_ptr这样:

std::unique_ptr<Player[]> players(new Player[1]);players[0] = Player(playerWIDth,1);

现在,unique_ptr将为您处理该分配,您不需要自己调用delete. (N.B.当你分配一个数组时,你应该给unique_ptr一个数组类型; std :: unique_ptr< Player []>,当你分配任何你使用非数组类型时,std :: unique_ptr< Player&gt ;.) 当然,C有一个更专业的R.A.I.I.用于管理数组的类型,std :: vector,您应该更喜欢使用std :: unique_ptr:

std::vector<Player> players(1);players[0] = Player(playerWIDth,1);

或者在C 11:

std::vector<Player> players { Player(playerWIDth,1) };
总结

以上是内存溢出为你收集整理的与C中的对象数组混淆全部内容,希望文章能够帮你解决与C中的对象数组混淆所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1254288.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存