Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this bad RAII design?

I come from a Java background, but I learned C++ after and have been programming with it for a few years now (mostly debugging and writing fixes, not designing programs from scratch). However, I ran into an issue today and frankly, I'm a little surprised it took this long to come across it.

Let's say I have a class named Class1 whose header file contains (among other code):

class Class1 {
    private:
        Class2 object;
}

The Class2 class doesn't have a default constructor specified. Now, in the Class1 constructor, I'm reading the binary header of a file and using the info I parse from that to initialize Class2, as shown with the pseudo-code below:

Class1::Class1(std::string) {
    // Read some binary info from a file here

    // Parse that binary info

    object2 = Class2(info);

In Java, since it's not using the RAII paradigm, that would be perfectly legal. However, since C++ uses RAII, object 2 was already initialized with its default constructor by the time I do object2 = Class2(info);. I couldn't have just called that constructor originally (in the Class1 header file) because I didn't have the info I needed to create object yet. However, I can't just make object2 local to the constructor, because I need other functions to be able to see/use it.

Clearly this doesn't work. What's the standard approach for this stuff? I actually thought about just changing Class1 to having a Class2 pointer like so:

class Class1 {
    private:
        Class2* objectPointer;
}

and then calling *objectPointer = Class2(info). However, "Class2" in my case is an ifstream and it seems that the operator= function has been deleted and doesn't work with either approach.

So... how do I do this?

like image 862
mtrewartha Avatar asked Dec 08 '22 21:12

mtrewartha


1 Answers

because your object is not const, that's all perfectly legal. However, if you want to initialise objects in the initialisation phase, you must provide the information. You can do that such

 Class1::Class1(std::string file_name) : object(InfoFromFile(file_name)) {}

where InfoFromFile() would either be a standalone function (declared in an anonymous namespace within a .cc file) or a static member function of Class1. If more information than file_name is required to generate the information needed for Class2, you can provide it to that function.

like image 68
Walter Avatar answered Dec 31 '22 23:12

Walter