【问题标题】:"Expression must be a modifiable LValue"“表达式必须是可修改的 LValue”
【发布时间】:2016-10-25 02:14:49
【问题描述】:

我正在尝试创建一个物理模拟,模拟所有 spaghettiObjects 上的物理并将其显示为文本。目前没有任何物理模拟,但那些会去写 //math 的地方

我在处理这段代码时遇到了问题。我是一个相当新的程序员,我从 java 开始,正在尝试学习 c++。错误在第 48,49,50 行,我试图用不同的方法调用做同样的事情。我无法弄清楚这里出了什么问题,当我删除 = worldObjectToUpdate.variable 时,它​​不再引发错误。

这里是所有代码

#include <iostream>
#include <string>
using namespace std;
//Created to hold the x, y, velocity and mass of an object.  
//It's called a spaghettiObject cause I was bored.
//A better name would probably be something like "worldObject"
struct spaghettiObject {
public:
    float velocity;
    float positionX;
    float positionY;
    float mass;
};
//All world objects in an array
spaghettiObject myArray[5];
//test zone
spaghettiObject test;
spaghettiObject createTestObject() {
    myArray[1] = test;
    test.mass = 2;
    test.positionX = 2;
    test.positionY = 2;
    test.velocity = 2;
    return test;
}
//Output from the physics simulation to the render function
spaghettiObject output;
//Calculates the position of a spaghettiObject's x using velocity
float nextPositionX(spaghettiObject objectToTransform) {
    float objectToTransformNewX = objectToTransform.positionX;
    //math
    return  objectToTransformNewX;
}
//Calculates the position of a spaghettiObject's x using velocity
float nextPositionY(spaghettiObject objectToTransform) {
    float objectToTransformNewY = objectToTransform.positionY;
    //math
    return objectToTransformNewY;
}
//Calculates the new velocity. for use:after updating x and y of object
float nextVelocity(spaghettiObject objectToUpdate) {
    float objectToUpdateNewV = objectToUpdate.velocity;
    //math
    return objectToUpdateNewV;
}
//Designed to be where all of the update functions are called
void updateWorldObject(spaghettiObject worldObjectToUpdate) {
    nextPositionX(worldObjectToUpdate) = worldObjectToUpdate.positionX;
    nextPositionY(worldObjectToUpdate) = worldObjectToUpdate.positionY;
    nextVelocity(worldObjectToUpdate) = worldObjectToUpdate.velocity;
}
//calculates position of variable defined above, myArray
void nextUpdateOfMyArray() {
    //temp object that is effectively the entire array
    spaghettiObject temp;
    //initilization of temp
    temp.mass = 0;
    temp.positionX = 0;
    temp.positionY = 0;
    temp.velocity = 0;
    //for calling functions for
    //each of the objects
    for (int i = 0; i++; i < (sizeof myArray / sizeof spaghettiObject)) {       
        //assigning the current object in the array to the temp object
        myArray[i] = temp;
        //Calling the update functions
        updateWorldObject(temp);
        //test
        createTestObject() = temp;
        //regular code
        output = temp;
    }
}
//Used to update the physics
void update() {
    nextUpdateOfMyArray();
}
//Used to render a console output
void render() {
    cout << output.mass + output.positionX + output.positionY + output.velocity;
}
int main() {
    update();
    render();
    cin.get();
}

【问题讨论】:

  • 还有,错误在哪一行?
  • 你的代码有几个问题。

标签: c++ expression lvalue


【解决方案1】:

functionCall() = value in updateWorldObject 是你的问题。您不能为函数调用赋值。你打算把这个价值放在哪里?如果你想要它在对象中,赋值的 lhs 应该是objectToModify.propertyToModifypointerToObject-&gt;propertyToModify。如果你想把它放在一个自变量中,lhs 是variableToModify。如果您希望它成为函数的参数,则没有赋值表达式。在任何情况下,分配给函数调用表达式都是没有意义的。

在这种情况下,您似乎正在尝试更新参数worldObjectToUpdate 的属性,但这也不起作用。原因是 c++ 中的参数是按值传递的,因此将参数声明为 SpaghettiObject 会告诉 c++ 将整个对象复制到调用堆栈上——这不是你在 java 中习惯的做法。然后,该新对象将在函数内部进行修改,但该对象在函数返回时消失。这就像打开一个文件,进行一些编辑,然后关闭它而不保存。

相反,您希望将参数声明为对象的引用。在java中,所有对象都是引用,所以你永远不会区分。在 C++ 中,有两种语法方式可以指示参数是引用,以便函数将修改您传递给它的对象,而不是克隆它并丢弃更改。

void function(Object* pointerToObject) {
    pointerToObject->propertyToModify = newValue;
}

Object anObject;
function(&anObject);

在这种情况下,引用是一个指针。它指向您正在使用的对象。当指针作为参数复制到堆栈上时,对象本身不会被复制,并且函数可以使用-&gt; 而不是. 来更改其属性或调用其方法。您必须使用运算符&amp; 获得指向对象的指针,例如&amp;anObject

引用对象的另一种语法方式更接近于您在 java 中使用的方式。

void function(Object& objectToModify) {
    objectToModify.propertyToModify = newValue;
}

Object anObject;
function(anObject);

Object&amp; 类型是一个Object 的引用,这几乎就是你从java 中想到的:你仍然使用. 运算符,你从不做任何事情特殊创建引用,对象不被复制。引用(相对于指针)的缺点是,一旦引用引用了一个对象,它就不能重新分配给另一个对象,但作为函数的参数就可以了。

【讨论】:

    【解决方案2】:

    createTestObject() = temp; 很可能是temp=createTestObject()

    【讨论】:

    • 另外,myArray[i] = temp;
    • 另外,spaghettiObject createTestObject() { myArray[1] = test; 您不希望将 myArray[1] 对象放入函数中,如果myArray[1] 在外面,以后调试它会更容易。
    猜你喜欢
    • 1970-01-01
    • 2011-08-25
    • 2019-06-28
    • 2020-07-07
    • 2017-08-27
    • 2021-09-17
    • 2014-12-15
    • 2014-12-20
    • 2015-09-19
    相关资源
    最近更新 更多