As far as I understand the RAII idiom when applied to resources needed by a class (and please correct me if I'm wrong), a class that requires a resource should define a member of the appropriate type, and its destructor will be called automatically when the using class instance is destroyed, like this:
class Skybox
{
public:
Skybox() : tex_(...) {}
private:
Texture tex_;
};
Apart from using a smart pointer to allocate the resource on the heap, how can this pattern be applied if the resource member requires some code to be executed in the Skybox
constructor, before the initialisation of the resource? For example:
class Skybox
{
public:
Skybox(const std::string& fileName);
private:
Texture tex_;
}
Skybox::Skybox(const std::string& fileName)
{
// read stuff from skybox initialization file
// including various texture parameters such as texture file
...
// initialize tex_ based on information read above
}
Update: the Texture
class requires all initialization to be performed in its constructor (i.e. no Texture::Init()
method is available)
Wrap the initialization code into a function, and use that function (member or non-member, static or non-static, as appropriate) to initialize the member variable:
Texture Skybox::init_tex(std::string const& fileName) {
// read stuff from file, including textureFile
// initialize result
return Texture(...);
}
Skybox::Skybox(std::string const& fileName):
tex_(init_tex(fileName))
{ }
The initialization function should probably be a static function. If it isn't, be careful not to use any members that haven't been initialized yet — you're calling init_tex
on a not-yet-fully initialized Skybox
instance.
Maybe you should encapsulate the creation of a texture into a free function as the reading of the file seems unrelated to the Skybox and could possibly useful somewhere else. I guess another name for this is Factory
.
Tex tex_from_file(const std::string&) {
// ...
}
class Skybox {
Skybox(const std::string& s) : tex_(tex_from_file(s)) {}
};
Even nicer would be a Skybox constructible from a Tex
object. However, this requires Tex
to be copy or move
constructible. If this isn't the case a proper workaround could be to
return a std::unique_ptr<Tex>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With