Initialize const members using complex function in

2019-07-20 18:13发布

I have a program that works with 3d grids. This grid has its own class object Grid that looks like this (simplified version):

class Grid
{
  public:
    Grid() { readDataFromInputFile(); }
  private:
    void readDataFromInputFile() {...} // this function reads the values for i, j, k from disk
    int i; int j; int k;
};

What I would like to do now, is to be able to set the variables i, j and k as const int, to avoid messing them accidentally up in the other functions. I can however not easily set them in a member initializer list, because they have to be read from file. I have been browsing through the existing discussions but I couldn't find an accurate discussion on this problem.

Is there a solution to be able to set them as const, and still be able to use a complex function to retrieve the data? In my real application, there are of course much more variables to be read, that are not allowed to change after initialization.

2条回答
Viruses.
2楼-- · 2019-07-20 18:52

One way to solve setting const memebers with complex behavioour is to initialize them using a functoin. In your case if I understand correctly, these members are initialized using one function call, so it's better if that function just return the members's value so that you can set the const memebers. Something that should look like this:

class Grid
{
  public:
    Grid() : data( readFromInputFile() ) {  }
  private:
    struct Data{
    int i; int j; int k;
    };
    const Data data;
};

This simple alternative should solve your problem. The only thing to change is the way you access the data, data.i instead of i. Once data is initialized (readFromInputFile() returning a Data too), it can't be changed.

If you need readFromInputFile() to not be a member or static member function, then move the definition of Data outside of the class or make it public.

查看更多
三岁会撩人
3楼-- · 2019-07-20 19:01

Don't break the One Responsibility Principle: A Grid should not be responsible of loading itself from a file, this is a responsibility of another component (For example a simple loading function):

class Grid
{
public:
    Grid( int ii , int jj , int kk ) : i{ ii } , j{ jj } , k{ kk }
private:
    const int i , j , k;
};

Grid loadGrid( constd std::string& filename )
{
    ...
};
查看更多
登录 后发表回答