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 ¢er;
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 ¢er;
and you are initializing that with Point(0,0,0)
.
You can just change the way you declared your members, from const Point ¢er;
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.