0

I was trying to return an object UnitCubeInstance, which is an instance of a class MeshObject. The MeshObject has a reference to the MeshAsset class.

My current way of doing this is of no luck, and when the object is returned, the MeshAsset is no longer accessible.

My question is, is the design shown below viable in any way? Or do I have to make MeshObject to hold actual instances of MeshAsset, which seems easy to do but not efficient on the memory.


The problematic code:

static MeshObject createUnitCubeInstance(Program &program) {
    auto unitCubeAsset = MeshAsset::UnitCube();
    auto unitCubeInstance = MeshObject(unitCubeAsset);
    return unitCubeInstance;
}

And a minimal version of the two classes:

class MeshAsset {
    // returns a general instance that is designed to be shared, 
    // kind of resemble a singleton
    static MeshAsset UnitCube();
}

class MeshObject {
    MeshAsset& asset;
    MeshObject(MeshAsset& asset);
}

If I missed something that is crucial for my example, please feel free to comment.

jackxujh
  • 983
  • 10
  • 31
  • I know C++ does not have ARC or stuff, and everything tends to be more manual, but I couldn't find how I could do it. – jackxujh Nov 20 '19 at 08:23
  • The `MeshObject` class you've shown us **does not** have a reference to anything. It doesn't have fields at all! Please post real code. Do you actually store `MeshAsset&` reference inside `MeshObject`? This won't work, because the `unitCubeAsset` variable dies after `createUnitCubeInstance` exits. Solutions are: either `UnitCube()` should return a (smart) pointer or you should make a copy inside `MeshObject` class. – freakish Nov 20 '19 at 08:36
  • @freakish thank you for pointing out! I added the `MeshAsset&` member to `MeshObject` class. I read some more posts, and realized that the `unitCubeAsset` will end its lifecycle after the function `createUnitCubeInstance` exits. Thank you for pointing out! I will look into smart pointer (haven't worked with it before). – jackxujh Nov 20 '19 at 08:51
  • I am reluctant to copy mesh asset to mesh object. Because each asset takes up MB of spaces, and there could easily be dozens or hundreds of them in the frame to be rendered (I should point out this is a computer graphics project) – jackxujh Nov 20 '19 at 08:53
  • @jackxujh This is a lifetime management problem. Somebody needs to be responsible for eventually cleaning up the `unitCubeAsset` you created. Right now that happens at the end of `createUnitCubeInstance`, which is too early. Maybe you want a central class that **owns** all created assets? Then (as long as said class lives longer than the `MeshObject`s) you can just store references in `MeshObject`. – Max Langhof Nov 20 '19 at 09:04

1 Answers1

2

The problem is, the local object you store a reference from is destroyed when you leave scope:

static MeshObject createUnitCubeInstance(Program &program) {
    auto unitCubeAsset = MeshAsset::UnitCube(); // <-- create a local object
    auto unitCubeInstance = MeshObject(unitCubeAsset); // <-- pass a local object as reference
    return unitCubeInstance; // pass object out
} // leave scope and break reference

Possible solutions:

Just in case: you need to declare auto& unitCubeAsset = ... in case you want to store a reference.

moooeeeep
  • 31,622
  • 22
  • 98
  • 187