Как мне исправить "начальное значение ссылки на неконстантное должно быть lvalue?" - PullRequest
0 голосов
/ 20 января 2019

Я работал над серией YouTube Хильце Вонк о том, как разрабатывать игры с использованием библиотеки SFML.Я близок к концу серии, и меня знакомят с обнаружением столкновений.Насколько я понимаю, Вонк использует класс «Коллайдер» и добавляет коллайдер к каждому объекту, который он хочет проверить на столкновение.Короче говоря, функции Collider регулярно используют & ссылаются, и я признаю, что я не всегда точно знаю, что происходит.

Так что я получил ошибку "первоначальное значение ссылки на неконстантное должно бытьlvalue. "Сначала я выяснил, что означает эта ошибка.Насколько я понимаю, я передаю const, когда функция не запрашивает const.Однако я не знаю, как это исправить.

Все еще надеясь решить проблему самостоятельно, я переучился, как передавать ссылки и как указатели, но я все еще не мог понять это.

Люди в комментариях к видео имели ту же проблему.Я полагаю, что Вонк использует более старую версию Visual Studio и более старую версию SFML.

Редактировать: я попытался немного урезать свой код.Если мне все еще нужно вырезать какой-то код, пожалуйста, дайте мне знать.

Кроме того, если вы хотите посмотреть конкретное видео, на которое я ссылаюсь, оно здесь: https://www.youtube.com/watch?v=l2iCYCLi6MU&t=442s

main.cpp (ошибка красного волнистости под игроком. GetCollider ())

#include <SFML\Graphics.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());

Collider.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;
};

Collider.cpp

#include "Collider.h"



Collider::Collider(sf::RectangleShape& body) :
    body(body)
{
}

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

Player.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;
};

player.cpp

#include "Player.h"

Player::Player(sf::Texture* texture, sf::Vector2u imageCount, float switchTime, float speed) :
    animation(texture, imageCount, switchTime)
{
}

Platform.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;

};

Platform.cpp

#include "Platform.h"

Platform::Platform(sf::Texture* texture, sf::Vector2f size, sf::Vector2f position)
{
}

Любойпомощь будет приветствоваться.

1 Ответ

0 голосов
/ 20 января 2019

Ошибка компиляции происходит здесь:

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

GetCollider() возвращает объект Collider. Часть «player.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)

Это позволит напрямую передать временное значение для этого параметра.

Обратите внимание, что это потребует дальнейших изменений в показанном коде. Методы other, которые вызываются из CheckCollision (), теперь должны быть const методами класса.

На самом деле стоит выполнить работу, чтобы внести это изменение, потому что оно научит вас некоторым довольно основным, но важным концепциям. Методы класса обычно делятся на две категории: те, которые не изменяют свой экземпляр класса, и те, которые делают. Те, которые не должны быть объявлены как const. Это позволяет вашему компилятору поймать вас на случайном изменении экземпляра класса, когда это не должно быть.

...