I have a class with a static variable. Since I need a constructor that isn't the default, I'm getting a little confused, but I hope I did it well
Class
class Object3D{
public:
static Object3D ObjControl;
Object3D(); //this is here just for the initialization of the static variable
Object3D(Triangle *mesh);
Triangle *mesh;
};
At this point I need to create an Object3D and I do as below
bool Engine::OnInit() {
if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
return false;
}
if((Surf_Display = SDL_SetVideoMode(WIDTH, HEIGTH, BBP, FLAGS)) == NULL) {
return false;
}
arma::colvec::fixed<3> upDirection;
upDirection << 0 << 1 << 0;
Camera cam(0.0, 0.0, 10.0, 10.0, 200.0, 90.0, upDirection);
Camera::CameraControl = cam;
arma::colvec::fixed<3> vertexA;
vertexA << -1 << 1 << 0;
arma::colvec::fixed<3> vertexB;
vertexB << 1 << 1 << 0;
arma::colvec::fixed<3> vertexC;
vertexC << 0 << -1 << 0;
Triangle tri(vertexA, vertexB, vertexC);
Triangle mesh[1];
mesh[0] = tri;
Object3D obj(mesh);
Object3D::ObjControl = obj; // PROBLEM! -> when the function extis from the OnInit ObjControl doesn't have anything inside.. it is like cleaned at the exit
return true;
}
The problem is the one that is inserted in the comment before the return.
Then when I need to pass that object to the rendering function, as below; the application closes because I'm trying to access to a location of memory not initialized
void Engine::OnRender(){
Rendering.WfRender(Object3D::ObjControl, Surf_Display, 1);
}
I think I'm doing something wrong with the static variable, but I did the same with a static variable for a Camera class, as you can see in the Engine::OnInit, and there everything works well. So I have no clue what's going on.
The main issue in your program is that you make a Triangle instance (mesh) in your function and that you pass a pointer to your static member variable ObjControl. When you leave the function, mesh is no longer available, so ObjControl points to an invalid instance. This could be solved by storing an actual Triangle instead of a pointer to a Triangle in Object3D or a container of Triangles if more are needed.
Does your Object3D class only hold onto the pointer to the mesh or take a copy of it?
Does it implement a deep-copy copy constructor?
I ask because your mesh is going out of scope after being assigned to obj, and obj is going out of scope after being assigned to the static variable. You need to either assign the mesh on the heap and hand that pointer to the static variable, or ensure the actual data is copied by correctly implementing the right constructors.
EDIT: Or, as this looks like games development, get it done quick and nasty! ;-)
Object3D::ObjControl.mesh = new Triangle(vertexA, vertexB, vertexC);
...and lose the local variables tri, mesh, and obj.
Related
I have a project where my textures are not displayed inside window properly. Instead of textures it will always show blank white sprites. I cant find out what I'am doing wrong. Here is my code:
class header with vector holding textures
class textures
{
public:
sf::Texture dirt_Texture;
sf::Texture grass_Texture;
std::vector<sf::Texture> texturesVector;
/*
dirt = 0
grass = 1
*/
public:
textures();
sf::Texture getTextureByID(int id);
};
and .cpp file for it:
//constructor populate vector with textures
textures::textures()
{
if (!dirt_Texture.loadFromFile("dirt.PNG"))
{
std::cout << "Error while loading texture.\n";
}
dirt_Texture.isSmooth();
texturesVector.push_back(dirt_Texture);
if (!grass_Texture.loadFromFile("grass.PNG"))
{
std::cout << "Error while loading texture.\n";
}
texturesVector.push_back(grass_Texture);
std::cout << "Texture constructor has been called.\n";
}
sf::Texture textures::getTextureByID(int id)
{
return texturesVector[id];
}
with child class sprite:
class sprites : public textures
{
private:
//textures* textureClass;
sf::Sprite sprite;
std::vector<int> textureIDsVector;
public:
sprites();
~sprites();
int getVectorValueAtLine(int &line);
void setVectorValueAtLineTo(int &line, int value);
void updateTextureAtLine(int& line);
sf::Sprite* getSprite();
};
where primary functions looks this in .cpp
sprites::sprites()
{
std::vector<int> cubeIDsVector(100, 0);
textureIDsVector = cubeIDsVector;
//textureClass = new textures();
std::cout << "Sprite constructor has been called.\n";
}
void sprites::updateTextureAtLine(int& line)
{
switch (textureIDsVector[line])
{
case 0:
//switcher = 0;
sprite.setTexture(getTextureByID(0));
sprite.setColor(sf::Color(55, 150, 150, 150));
std::cout << "case 0\n";
break;
case 1:
//switcher = 1;
sprite.setTexture(getTextureByID(1));
sprite.setColor(sf::Color(155, 50, 150, 150));
std::cout << "case 1\n";
break;
default:
break;
}
}
at main loop I create sprite object on the heap after sf::RenderWindow and after window.clean(...) call updateTextureAtLine() function from the for loop.
No error returned and at debug it seems fine too, I am new into it but it was looking like texture is always at memory, I cant find out where is the problem.
Solved as described below.
getTextureByID() returns a copy of a texture and not a reference. This copy is destroyed when it goes out of scope - so as soon as the call to sprite.setTexture() finishes.
This results in the Sprite having a pointer to a texture that no longer exists.
The solution is to instead return a pointer or a reference from getTextureByID(). Whilst we are changing that function we could should also make the function and returned value const as we are not planning on modifying it, although this is optional - it is a good habit I might as well point out.
Here is an example of a const function that returns a const reference:
// header
const sf::Texture& getTextureByID(int id) const;
// source
const sf::Texture& textures::getTextureByID(int id) const {
return texturesVector[id];
}
This should hopefully solve your problem.
Unrelated notes:
Your textures class is storing four textures total, two dirt textures, and two grass textures.
This might be what you intended, or this might not be.
One solution is to not have the member variables dirt_Texture and grass_Texture or just not to have texturesVector.
The other solution is to make texturesVector store pointers to textures, these could also be const and this would look like this:
// header
std::vector<const sf::Texture*> texturesVector;
// source
// constructor
texturesVector.push_back(&dirt_Texture);
...
texturesVector.push_back(&grass_Texture);
// getTextureByID()
return *texturesVector[id]; // (or alternatively return a pointer)
Finally, if you ARE storing texture objects inside of texturesVector (if you switch to pointers this won't be a problem), then note that adding any more textures might force the internal array of the vector to change memory location and thus invalidate your textures.
If you are not planning on adding more textures midway through running the program, then that is ok. I do add textures midway through running programs a lot because I like lazy initialization. If you are planning on adding more textures, then either use another container that does not move it's objects, or dynamically allocate a place for your textures. I am a fan of the latter, using a map of strings to unique pointers of textures (std::unordered_map<std::string, std::unique_ptr<sf::Texture>>)
I added a destructor to some code and it seems to be calling early and causing problems. I added a debug statement to see where it is being called and that made me even more confused. I understand that managing my own memory is not best practice but I wanted to try it out myself.
This is basically my GameObject class:
class GameObject
{
public:
int xCoord = 0, yCoord = 0, prevX, prevY;
int status = 0, weight = -1;
int id = -1;
GameObject(CommandComponent* commands,
PhysicsComponent* physics,
GraphicsComponent* graphics)
: commandComponent(commands),
physicsComponent(physics),
graphicsComponent(graphics)
{};
~GameObject()
{
std::cout << "Destructor called " << id << std::endl;
delete commandComponent;
delete physicsComponent;
delete graphicsComponent;
};
void update(World& world, int command, sf::Time dt)
{
commandComponent->update(*this, world, command);
physicsComponent->update(*this, world);
graphicsComponent->update(*this, dt);
};
void update(World& world, int command)
{
commandComponent->update(*this, world, command);
physicsComponent->update(*this, world);
};
sf::Sprite draw()
{
return *(graphicsComponent->draw());
};
void setCoords(int x, int y)
{
prevX = xCoord;
xCoord = x;
prevY = yCoord;
yCoord = y;
};
void setId(int newId)
{
id = newId;
}
private:
CommandComponent* commandComponent = NULL;
GraphicsComponent* graphicsComponent = NULL;
PhysicsComponent* physicsComponent = NULL;
};
This is the createPlayer Method:
GameObject* createPlayer(sf::Texture* text)
{
return new GameObject(new PlayerCommandComponent(), new PlayerPhysicsComponent(), new PlayerGraphicsComponent(text));
};
This is a method I invoke to add the new object to a vector based on if it is an active object or an inactive one I also add it to an array :
void World::addObject(GameObject object, int id, int type){
object.setId(id);
if (type == 0)
{
inactiveObjects.push_back(object);
}
else if (type == 1)
{
activeObjects.push_back(object);
}
}
Finally this is my test code that creates the Game Objects and calls the above function and where I see the destructors being called from:
void World::test()
{
// Player
std::cout << "Starting to create id 0\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 0, 1);
activeObjects.at(0).setCoords(3, 3);
activeObjects.at(0).weight = 10;
std::cout << "Created id 0\n";
// Test Objects
std::cout << "Starting to create id 1\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 1, 1);
activeObjects.at(1).setCoords(3, 4);
activeObjects.at(1).weight = 7;
std::cout << "Created id 1\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 2, 1);
activeObjects.at(2).setCoords(5, 4);
activeObjects.at(2).weight = 2;
addObject((*createPlayer(&(mTextures.get(Textures::Enemy)))), 3, 1);
activeObjects.at(3).setCoords(6, 6);
activeObjects.at(3).weight = -1;
addObject((*createPlayer(&(mTextures.get(Textures::Enemy)))), 4, 1);
activeObjects.at(4).setCoords(1, 1);
activeObjects.at(4).weight = 0;
std::cout << "Done Creating Test Objects\n";
I guess my main question is how come the Destructors are being called? Im assuming its related to how I'm constructing the object in the createPlayer method, Perhaps it's going out of scope after I return it but I thought using the new keyword would prevent that from happening? I'm puzzled here.
Several things at play here.
GameObject* createPlayer(sf::Texture* text)
returns a dynamically allocated GameObject. This could be done better, read up on std::unique_ptr, but there is nothing strictly wrong here. I mention it mostly to point out std::unique_ptr and set up
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 0, 1);
because this is where thing start to go wrong. When you find code that uses new and dereferences and discards the the result, you're looking at a memory leak. You've lost the pointer to the dynamically allocated object and without the pointer it is next to impossible to find the allocation again so that you can delete it.
Storing the dereferenced object will invoke either the copy constructor or the assignment operator and at this point you need to consider The Rule of Three: If you need a to define a custom destructor, you probably need to define a custom assignment operator and a copy constructor. This is a standard example of when you need to observe the Rule of Three. What goes wrong is well-explained in the Rule of Three Link, so stop, read, and understand it before going any further. Failure to do this means the rest of this answer will be nigh-useless to you.
You cannot write good, non-trivial C++ code without a firm grip on the Rule of Three and all of its friends.
You can step around the Rule of Three here by changing
void World::addObject(GameObject object, int id, int type)
to
void World::addObject(GameObject * object, int id, int type)
and pass object by reference. This doesn't help much because
inactiveObjects.push_back(object);
is expecting an object, not a pointer.
You can change that as well, but should you? std::vector is at its absolute best when it directly contains an object. Pointers lead to pointer chasing, poor caching behaviour and ultimately suuuhhhfering. Don't store pointers unless you have a compelling reason to do so.
And if you do, manage the pointers with a std::unique_ptr beginning to end.
What I would do:
Jump straight over the Rule of Three and go to The Rule of Five.
Exterminate as many dynamically allocated variables as possible so that I don't need to do much work, if any, with point 2. This means no pointers for (or in) commandComponent, physicsComponent and graphicsComponent if possible.
Add a move constructor and move assignment operator to GameObject as well as CommandComponent, PhysicsComponent, and GraphicsComponent. Keep all resource management as close to the resource as possible. This allows you to keep higher level classes as ignorant as possible. If GraphicsComponent knows how to copy and move itself, GameObject doesn't need to know how to move it. This allows you to take advantage of The Rule of Zero, and the Rule of Zero should be what you strive for in all of your classes.
Use move semantics to get a GameObject, not a GameObject* from createPlayer down to the activeObjects and inactiveObjects vectors.
Enjoy the reduced memory management load.
I'm making a game with SDL that used libconfig to read some settings from a file. The problem is that I made a class called ClipList that contains a std::vector<SDL_Rect> to store the settings but when trying to add SDL_Rect objects to the vector, for some reason push_back does nothing and I end up with an empty vector.
This is the class:
class ClipList
{
public:
ClipList();
ClipList(int);
virtual ~ClipList();
void addClip(int,int,int,int);
void getClip(int,SDL_Rect*);
int getLength();
protected:
private:
std::vector<SDL_Rect> clips;
};
ClipList::ClipList(int l)
{
clips.reserve(l);
}
void ClipList::addClip(int x,int y,int w,int h){
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
clips.push_back(rect);
}
void ClipList::getClip(int i,SDL_Rect* rect){
rect = &(clips.at(i));
}
int ClipList::getLength(){
return clips.size();
}
And this is the function where I initialize the ClipList object. This function gets called from main.
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips){
const Setting& root = placlips->getRoot();
int x,y,w,h;
try{
Setting& clipsett = root["clips"];
int cliplen = clipsett.getLength();
clips = new ClipList(cliplen);
flipclips = new ClipList(cliplen);
for(int i=0;i<cliplen;i++){
const Setting& c = clipsett[i];
if(!(c.lookupValue("x",x)&&c.lookupValue("y",y)&&c.lookupValue("w",w)&&c.lookupValue("h",h))){
continue;
}
clips->addClip(x,y,w,h);
}
}catch(const SettingNotFoundException &nfex){
cerr << "Setting not found at" << nfex.getPath() << endl;
}
}
Regardless of whether the ClipList objects get initialized in main or set_clips, clips.push_back(rect) doesn't work. The capacity of the vector changes but no object gets stored so I end up with a segfault if I try to do anything else with the vector, even checking if the vector is empty or not.
I am going to guess, the signature of the function
void set_clips(Config* placlips,ClipList* clips, ClipList* flipclips);
is the culprit. You are allocating memory for clips and flipclips in this function but since the pointers are passed by value, the calling function does not see the allocated memory.
If you change the function signature to:
void set_clips(Config* placlips, ClipList*& clips, ClipList*& flipclips);
your problems should go away.
clips.push_back(rect) is working fine. Your set_clips function allocates new ClipList instances but does not pass those pointers back to the caller. The caller is probably attempting to use a garbage pointer as an initialise instance and that is why you are getting a segfault.
You need to pass the created objects back. You should use something like std::shared_ptr<> to do that instead of bare pointers.
Update on how to do this without using std::shared_ptr<>:
You need to keep track of ownership and deal with exceptions. In terms of the actual passing, the rule I use (originally from Lakos in "Large Scale C++ Software Design") is that parameters that are return values (as you are attempting to use them) are pointers, and read-only parameters are by value or const-reference. Return values come first.
So, your set_clips function should look like this:
void set_clips(ClipList** clips, ClipList** flip_clips, Config const& placlips)
When you call set_clips you pass a pointer to each pointer that will receive the allocated value, and pass a const-reference to the placlips object that is not modified by the function.
You would all it something like this:
ClipList* clips = 0;
ClipList* flip_clips = 0;
set_clips(&clips, &flip_flips, placlips);
// ... then do whatever comes next.
But combining those rules with std::shared_ptr<> or boost::shared_ptr<> is better and the "modern C++" style.
I have a pretty standard class with some public member functions and private variables.
My problem originally stems from not being able to dynamically name object instances of my class so I created an array of pointers of the class type:
static CShape* shapeDB[dbSize];
I have some prompts to get info for the fields to be passed to the constructor (this seems to work):
shapeDB[CShape::openSlot] = new CShape(iParam1,sParam1,sParam2);
openSlot increments properly so if I were to create another CShape object, it would have the next pointer pointing to it. This next bit of code doesn't work and crashes consistently:
cout << shapeDB[2]->getName() << " has a surface area of: " << shapeDB[2]->getSA() << shapeDB[2]->getUnits() << endl;
The array of pointers is declared globally outside of main and the get() functions are public within the class returning strings or integers. I'm not sure what I'm doing wrong but something relating to the pointer set up I'm sure. I'm writing this code to try and learn more about classes/pointers and have gotten seriously stumped as I can't find anyone else trying to do this.
I'm also curious as to what the CShape new instances get named..? if there is any other way to dynamically create object instances and track the names so as to be able to access them for member functions, I'm all ears.
I've tried all sorts of permutations of pointer referencing/de-referencing but most are unable to compile. I can post larger chunks or all of the code if anyone thinks that will help.
class CShape {
int dim[maxFaces];
int faces;
string units;
string type;
string name;
bool initialized;
int slot;
public:
static int openSlot;
CShape();
CShape(int, string, string); // faces, units, name
~CShape();
void initialize(void);
// external assist functions
int getA(void) {
return 0;
}
int getSA(void) {
int tempSA = 0;
// initialize if not
if(initialized == false) {
initialize();
}
// if initialized, calculate SA
if(initialized == true) {
for(int i = 0; i < faces; i++)
{
tempSA += dim[i];
}
return(tempSA);
}
return 0;
}
string getUnits(void) {
return(units);
}
string getName(void) {
return(name);
}
// friend functions
friend int printDetails(string);
};
// constructor with values
CShape::CShape(int f, string u, string n) {
initialized = false;
faces = f;
units = u;
name = n;
slot = openSlot;
openSlot++;
}
My guess is you use the CShape constructor to increment CShape::openSlot?
You're probably changing the value before it's read, thus the pointer is stored in a different location.
Try replacing openSlot with a fixed value to rule out this CShape::option.
-- code was added --
I'm pretty sure this is the problem, the constructor is executed before the asignment, which means the lhs. will be evaluated after CShape::openSlot is incremented.
I apologize since this is rather a n00bish question, but I can't figure this one out.
class View //simplified
{
public:
ROILine* ROI() {return _roi;} //setter does some control stuff...
private:
ROILine *_roi;
}
class ROI : public eq::Object
{
public:
//virtual ROI(ROI* copy) = 0;
virtual ~ROI() {};
virtual uint32_t getType() = 0;
virtual void reset() = 0;
virtual bool addPoint( eq::Vector3f point ) = 0;
virtual bool previewPoint( eq::Vector3f point ) = 0;
virtual bool getNotationLocation( eq::Vector3f& point ) = 0;
virtual bool draw() = 0;
protected:
enum ROIType {
NONE = 0,
LINE,
POLY,
AREA,
VOLUME
};
enum ROIMeasure {
RM_LENGTH = 1,
RM_AREA,
RM_VOLUME,
};
private:
};
class ROILine : virtual public ROI
{
public:
ROILine();
ROILine(ROILine* copy);
ROILine(const ROILine& copy);
virtual ~ROILine() {SFLog(#"Destroying ROILine: 0x%x",this);};
void reset();
float distance() { return _start.distance(_end); }
// ROI Interface
uint32_t getType() { return ROI::LINE; }
virtual bool draw();
bool addPoint( eq::Vector3f point );
bool previewPoint( eq::Vector3f point );
bool getNotationLocation( eq::Vector3f& point );
eq::net::DataOStream& serialize(eq::net::DataOStream& os) ;
eq::net::DataIStream& deserialize(eq::net::DataIStream& is) ;
protected:
enum ROILineState { // RLS_
RLS_RESET,
RLS_START,
RLS_PREVIEW,
RLS_END,
};
private:
uint32_t _state;
eq::Vector3f _start;
eq::Vector3f _end;
};
ROILine::ROILine(const ROILine& copy) : ROI()
{
reset();
switch (copy._state)
{
case RLS_PREVIEW:
case RLS_END:
addPoint(eq::Vector3f(copy._start));
addPoint(eq::Vector3f(copy._end));
break;
case RLS_START:
addPoint(eq::Vector3f(copy._start));
break;
case RLS_RESET:
default:
break;
}
}
/*!
#abstract resets the line values and state
*/
void ROILine::reset()
{
_state = RLS_RESET;
_end = eq::Vector3f::ZERO;
_start = eq::Vector3f::ZERO;
}
/*!
#abstract if it has 2 points, draw the line. (_state > _PREVIEW)
#discussion assumes GL is already set up. Executes drawing commands.
#result true if the line was drawn
*/
bool ROILine::draw()
{
bool retVal = false;
if (_state >= RLS_PREVIEW) {
//glTranslatef(0.0f, 0.0f, -1.0f); //Back Up?
glColor3f( 1.0f, 0.0f, 0.0f ); //Red
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1 );
glBegin( GL_LINES );
{
glVertex3fv( _start.array );
glVertex3fv( _end.array );
}
glEnd();
//glTranslatef(0.0f, 0.0f, 1.0f); // Return
retVal = true;
}
return retVal;
}
// Elsewhere...
View *v = getView(); // returns the view object
// Destroys each time, but works wonderfully
ROILine r = ROILine(*(v->ROI()));
r.draw();
// Does not work (EXC_BAD_ACCESS)
v->ROI()->draw();
// Does not work (EXC_BAD_ACCESS on draw());
ROILine *r = v->ROI();
r->draw(); // debug shows r != 0x0
The Errors I get are as follows when I break on r->draw() and continue.
[Switching to process 12453]
Current language: auto; currently objective-c++
Warning: the current language does not match this frame.
(gdb) continue
Program received signal: “EXC_BAD_ACCESS”.
The "EXC_BAD_ACCESS" occurs on r->draw() or v->ROI()->draw() It doesn't step into the program at all, just halts and bt gives me a ??
My copy constructor works, because the draw() function actually draws where it's supposed to (instead of !!##$!4!## land) What I don't udnerstand, is why copying the value works, but accessing v->ROI()->draw() does not. it MUST have v->ROI() in order to make the copy!!
yes? ... no?
so confused...
Thanks,
Assuming that everything in your copy constructor for ROILine is working correctly, then here is a possibility: Something has overwritten a few bytes of the ROILine instance returned by View::ROI().
Most likely, the first several bytes of a ROILine object contain a pointer to the virtual function table for that class. (At least this is what typical C++ implementations do.) If those bytes get overwritten then instead of calling through the virtual function table, the program would end up calling through garbage and would almost certainly crash.
However, when making a copy of an object through a copy constructor, that pointer to the virtual function table is probably not accessed at all (unless you were to make a call to a virtual function in the copy constructor). In that case, all the data is copied successfully to a new object that has a correct vtable pointer.
Since draw is vritual, this would explain why calling it on the copy works while calling it on the original does not.
If this is what is happening, then you need to figure out what is overwriting part of your ROILine instance. If that instance is part of another object, then it may be easy. If that instance has been heap allocated individually, then it could be somewhat harder.
I think there's something strange going on.
You said code containing this line works wonderfully:
ROILine r = ROILine(*(v->ROI()));
In this line you perform *(v->ROI()) successfully.
But you said that if you try to do ROILine *r = v->ROI() then the value of r is NULL.
I don't think these can both be true (because that would mean you've successfully dereferenced a NULL pointer). I can think of two reasons for this:
Calling them sequentially does not work. If you move the "works wonderfully" block below the others, does it fail? If so, you may be copying a pointer and destroying it or the data it refers to. Then later, the data is not accessible.
The private ROILine* member of the View class is not set or initialized properly. Sometimes, this can lead to strange stochastic behavior; one compiled version (with the "works wonderfully block") may randomly initialize that member to be a nonzero value, while another compiled version (with one of the failing blocks) may randomly initialize that member to be zero. I've heard this referred to as a "Heisenbug" because trying to print out debugging information may change the problem.
Also, make sure you've verified that r is NULL after the line setting its value is executed. Some compilers initialize pointers to NULL and it may have not been set yet. Also check to make sure you have optimizations turned off; sometimes debuggers don't play well with optimizations, which can make a line of code execute after you think it's been executed.
The symptoms make it sound like your ROILine object has been deleted, leaving you with a dangling pointer to freed memory. When you try to call a virtual function, it crashes, because the vtable has been overwritten, but when you create a copy with the copy constructor it gets at least some valid data from the freed object, and appears to work.
I think ROILine should inherit from ROI.
Make draw virtual in ROILine and then
ROILine *r = v->ROI();
r->draw(); // debug shows r != 0x0
should work...
Connected to the problem (or not) It's a bad practice to call a function returning your ROI exactly like ROI constructor.
(referring to: ROILine* ROI() {return _roi;} //setter does some control stuff... )
Maybe the compiler gets confused...
Your copy constructor works as it takes a reference, and to do this you feed it a dereferenced (possibly null) pointer. This is one of those funny things in the language, as a reference to a dereferenced pointer doesn't actually dereference the pointer until you use the reference (C++ really is multi paradigm, it's even lazy!). Since this is undefined behavior, its only by chance that the copy constructor works at all. Its possible that in the View you've invalidated the pointer somehow.
#include <iostream>
using namespace std;
int addOne(int const & n) {
return n + 1; // Uh oh.
}
int main() {
int * ptr = 0;
cout << addOne(*ptr) << endl; // Doesn't crash here.
return 0;
}