如何修复"initial value of reference to non-const must be an lvalue?"

How do I fix "initial value of reference to non-const must be an lvalue?"

本文关键字:be must an lvalue non-const reference initial 何修复 value of to      更新时间:2023-10-16

我一直在研究Hilze Vonck的YouTube系列,介绍如何使用SFML库开发游戏。 我即将结束本系列,正在介绍碰撞检测。 据我了解,Vonck 使用一个名为"Collider"的类,他为每个想要检查碰撞的对象添加一个碰撞体。 长话短说,Collider 函数经常使用和引用,我承认我并不总是知道发生了什么。

所以我得到了错误"对非常量的引用的初始值必须是左值"。 首先,我研究了这个错误的含义。 据我了解,当函数不要求常量时,我正在传递一个常量。但是,我不知道如何解决它。

仍然希望自己解决问题,我重新学习了如何传递引用以及如何传递指针,但我仍然无法弄清楚。

视频评论中的人也有同样的问题。 我相信Vonck使用旧版本的Visual Studio和旧版本的SFML。

编辑:我试图稍微修剪我的代码。如果我仍然需要删减一些代码,请告诉我。

另外,如果您想查看我引用的特定视频,请在此处:https://www.youtube.com/watch?v=l2iCYCLi6MU&t=442s

main.cpp (红色波浪线错误在播放器下方。GetCollider())

#include <SFMLGraphics.hpp>
#include "Player.h"
#include "Platform.h"
Player player(&playerTexture, sf::Vector2u(3,9), 0.3f, 100.0f);
Platform platform1(nullptr, sf::Vector2f(400.0f, 200.0f), sf::Vector2f(500.0f, 200.0f));
Platform platform2(nullptr, sf::Vector2f(400.0f, 200.0f), sf::Vector2f(500.0f, 0.0f));
player.Update(deltaTime);
platform1.GetCollider().CheckCollision(0.0f, player.GetCollider());
platform2.GetCollider().CheckCollision(0.0f, player.GetCollider());

对撞机.h

#pragma once
#include <SFML/Graphics.hpp>
class Collider
{
public:
Collider(sf::RectangleShape& body);
~Collider();
void Move(float dx, float dy) { body.move(dx, dy); }
bool CheckCollision(float push, Collider & other );
sf::Vector2f GetPosition() { return body.getPosition(); }
sf::Vector2f GetHalfSize() { return body.getSize() / 2.0f; }

private:
sf::RectangleShape& body;
};

对撞机.cpp

#include "Collider.h"

Collider::Collider(sf::RectangleShape& body) :
body(body)
{
}
bool Collider::CheckCollision(float push, Collider & other)
{
//check collision
}

玩家.h

#pragma once
#include <SFML/Graphics.hpp>
#include "animation.h"
#include "Collider.h"
class Player
{
public:
Player(sf::Texture* texture, sf::Vector2u imageCount, float switchTime, float speed);
~Player();
public:
void Update(float deltaTime);
sf::Vector2f getPosition() { return body.getPosition(); }
Collider GetCollider() { return Collider(body); }
private:
sf::RectangleShape body;
};

播放器.cpp

#include "Player.h"
Player::Player(sf::Texture* texture, sf::Vector2u imageCount, float switchTime, float speed) :
animation(texture, imageCount, switchTime)
{
}

平台.h

#pragma once
#include <SFML/Graphics.hpp>
#include "Collider.h"
class Platform
{
public:
Platform(sf::Texture* texture, sf::Vector2f size, sf::Vector2f position);
~Platform();
void Draw(sf::RenderWindow& window);
Collider GetCollider() { return Collider(body); }
private:
sf::RectangleShape body;
};

平台.cpp

#include "Platform.h"
Platform::Platform(sf::Texture* texture, sf::Vector2f size, sf::Vector2f position)
{
}

欢迎任何帮助。

编译错误发生在这里:

platform1.GetCollider().CheckCollision(0.0f, player.GetCollider());

GetCollider()返回一个Collider对象。"玩家。此表达式的 GetCollider()" 部分是临时Collider值。CheckCollision声明如下:

bool Collider::CheckCollision(float push, Collider & other)

C++禁止将临时对象作为非常量引用参数传递。最简单的解决方法是简单地将临时对象存储在某个地方,首先:

Collider c=player.GetCollider();
platform1.GetCollider().CheckCollision(0.0f, c);

其他类似的调用也需要修复。但更合适的解决方法是将参数更改为const引用:

bool Collider::CheckCollision(float push, const Collider &other)

这将允许为此参数直接传递临时。

请注意,这将需要对显示的代码进行进一步更改。从CheckCollision() 调用的other方法现在必须const类方法。

实际完成此更改的工作是值得的,因为它会教您一些相当基本但重要的概念。类方法通常分为两类:不修改其类实例的方法和修改其类实例的方法。那些不应该被声明为const.这允许编译器发现您在不应该修改类实例时意外修改了类实例。

相关文章: