Home > Blockchain >  C : Variable that is passed by const referance changes value
C : Variable that is passed by const referance changes value

Time:11-26

for an assignment I was provided with a framework of different classes that use parameters passed by const reference. When I initialize one instance of this same class and then a second one later, the values of the members that were passed by const reference within the first one change.
I am not allowed to change a_cameras. Is there anything I can do within the class definition so that I avoid the values just changing on their own?

Initialization of PerspectiveCamera:

#include <core/image.h>
#include <core/point.h>
#include <core/vector.h>
#include <core/scalar.h>
#include <core/julia.h>
#include <rt/ray.h>
#include <rt/cameras/perspective.h>
#include <rt/cameras/orthographic.h>
#include <iostream>
#include <rt/renderer.h>

using namespace rt;


void a_cameras() {
    Image img(800, 800);
    Image low(128, 128);

    PerspectiveCamera pcam(Point(0, 0, 0), Vector(1, 0, 0.1f), Vector(0, 0, 1), pi/3, pi/3);
    Renderer r1(&pcam,0);
    r1.test_render2(img);
    r1.test_render2(low);
    img.writePNG("a1-2.png");
    low.writePNG("a1-2-low.png");

    PerspectiveCamera pcam2(Point(0, 0, 0), Vector(0.5f, 0.5f, 0.3f), Vector(0, 0, 1), pi * 0.9f, pi * 0.9f);
    Renderer r12(&pcam2,0);
    r12.test_render2(img);
    img.writePNG("a1-3.png");

    OrthographicCamera ocam(Point(0, 0, 0), Vector(0.1f, 0.1f, 1), Vector(0.2f, 1.0f, 0.2f), 10.f, 10.f);
    Renderer r2(&ocam,0);
    r2.test_render2(img);
    img.writePNG("a1-4.png");
}

Definition of PerspectiveCamera perspective.cpp:

#include <rt/cameras/perspective.h>
#include <cmath>
#include <core/matrix.h>

namespace rt {

PerspectiveCamera::PerspectiveCamera(const Point& center, const Vector& forward, const Vector& up, float verticalOpeningAngle, float horizontalOpeningAngle)
: center(center), forward(forward)
{
    vertFactor = tanf(verticalOpeningAngle / 2.0f);
    horFactor = tanf(horizontalOpeningAngle / 2.0f);
    x_axis = cross(forward, up).normalize();
    up_axis = cross(x_axis, forward).normalize();
    //vertFactor = tanf(verticalOpeningAngle / 2.0f);
    //horFactor = tanf(horizontalOpeningAngle / 2.0f);
}

Ray PerspectiveCamera::getPrimaryRay(float x, float y) const {
    printf("center: (%f, %f, %f); forward: (%f, %f, %f); x_axis: (%f, %f, %f); up_axis: (%f, %f, %f)\n",
           center.x, center.y, center.z,forward.x, forward.y, forward.z, x_axis.x, x_axis.y, x_axis.z, up_axis.x, up_axis.y, up_axis.z);
    Vector direction = x * x_axis * horFactor   y * up_axis * vertFactor   forward;
    return {center, direction};
}

}

perspective.h:

#ifndef CG1RAYTRACER_CAMERAS_PERSPECTIVE_HEADER
#define CG1RAYTRACER_CAMERAS_PERSPECTIVE_HEADER

#include <rt/cameras/camera.h>
#include <core/vector.h>
#include <core/point.h>

namespace rt {

class PerspectiveCamera : public Camera {
public:
    PerspectiveCamera(
        const Point& center,
        const Vector& forward,
        const Vector& up,
        float verticalOpeningAngle,
        float horizontalOpeningAngle
        );

    virtual Ray getPrimaryRay(float x, float y) const;

    const Point &center;
    const Vector &forward;
    Vector x_axis;
    Vector up_axis;
    float vertFactor;
    float horFactor;
};

}


#endif

Thank you, Jane

CodePudding user response:

Your code is rather complicated. Though much less is needed to see that the assumption: "A const reference does not change its value." is based on a misunderstanding.

#include <iostream>
    
struct foo {
    const int& x;
};

int main()
{
    int a = 42;
    foo f{a};
    a = 0;
    std::cout << f.x;
}

The output of this is 0 even though f.x was initialized with a when a had the value 42. f holds a constant reference to a. This merely implies that you cannot modify a via f.x. It does not imply that x cannot be modified through other means. A constant reference is not a reference to a constant!

CodePudding user response:

The answer from 463035818_is_not_a_number, says something absolutely correct.

But in your case, I think your problem is the fact you are storing references to temporary variables.

you have: const Point &center; and you are initializing that with Point(0,0,0).

You can just change the way you declared your members, from const Point &center; to Point center; and from const Vector &forward; to Vector forward;

This way you will not storing references, but actual copy of those objects. You can keep the const modifier you think it's essential for those members.

  • Related