简体   繁体   中英

Initialise const member variables in class using values from file input

I want to define a const variable which is part of a class like:

// camera.h
class Camera{
public:
    Camera(std::string file);
    ~Camera() {}
    const size_t FRAME_HEIGHT;
    const size_t FRAME_WIDTH;
private:
    std::string file;
    cv::VideoCapture cap;
    Read();
};

_____________________________________

// camera.cpp
Camera::Camera(std::string file) : file("settings.yml") {
    //...
    read();
    cap.open(0);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT);
    cap.set(CV_CAP_PROP_FRAME_WIDTH, FRAME_WIDTH);
}

void Camera::read(){
    // read something
}

However this does not work using an initialisation list because I first have to read this data from a settings file.

After calling read() I set my const variables FRAME_HEIGHT and FRAME_WIDTH .

Is it possible to leave them const and if yes how/where should I do that?

One option is to initialize a settings object from a file, and take needed values from it:

class Camera
{
    // note this section is moved to the beginning,
    // so file and settings are initialized before FRAME_HEIGHT and FRAME_WIDTH
private:
    std::string file;
    Settings settings;
public:
    Camera(std::string file)
        : file(file)
        , settings(file)
        , FRAME_HEIGHT(settings.getFrameHeight())
        , FRAME_WIDTH(settings.getFrameWidth())
    {
    }

    ~Camera() {}
    const size_t FRAME_HEIGHT;
    const size_t FRAME_WIDTH;
};

Also it could make sense to rewrite Camera constructor after that as

    Camera(const Settings& settings)
        : FRAME_HEIGHT(settings.getFrameHeight())
        , FRAME_WIDTH(settings.getFrameWidth())
    {
    }

-- this way you can take settings from anywhere, not only from a file.

It is possible if you use an intermediate class, like this:

class Camera {
    struct Reader {
        int value;

        Reader(bool x) {
            // Do whatever you like
            value = x ? 42 : 0xDEAD;
        }
    };
    Camera(Reader&& r) : value(::std::move(r.value)) { }

public:
    int const value;

    template<typename... V>
    Camera(V... args)
    : Camera(Reader(std::forward<V>(args)...))
    { }
};

This effectively adds another stage to the initialization, but still keeps encapsulation ( Reader and the corresponding constructor are private to Camera !). The performance impact should be negligible (forward and move operations are usually cheap), unless you initialize millions of these objects in some tight inner loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM