简体   繁体   中英

Make variable unchangeable without copying in C++

I'm working on some code in which a variable of type std::vector<double> is declared, before the value is specified. I can't define the value together with declaration, because it takes many lines of code to set the value. The thing is that this variable is a constant in essence, meaning it shouldn't be modified once it's set. However, it can't be declared const .

One way is to create another variable which is const and copy the value into it. const std::vector<double> a(b); would do, and use a instead of b in the program. However, my variable can be large and I wish to learn a way other than having to perform copying.

Any suggestions from you guys?

You may create a function to initialize it. In worst, you have a move . at best you have (N)RVO (return value optimization).

std::vector<Object> CreateBigVector();

And then

const std::vector<Object> myObject = CreateBigVector();

I think the problem is about scoping . You have to separate your problem into two different scopes :

  • a scope where you build up your vector
  • a (or others) scope(s) where you use it

In the scope where you build up your vector , it logically isn't a const variable. Once you have built it, you want it not to be changed anymore. So you may want to refer to it through a const & .

I'd go this way:

  • define a function std::vector<double> build_up()
  • inside build_up , you define a non-const vector and you can build it
  • when you're done, you can return it by value ( RVO will avoid any copy)
  • refer to the object returned by build_up() as a const object

Ie

const std::vector<double> v = build_up();

One way is to create a function

std::vector<Object> CreateYourVector();

and use it to initialise

const std::vector<Object> vec = CreateYourVector();

Another (technically a variation) is to create a helper class that contains your vector, and do all the work in a constructor

class Helper
{
     std::vector<Object> vec;

     public:

         Helper()
         {
               // initialise your vector here
         };

         const std::vector<Object> &TheVec() const {return vec;};
};

const Helper helper;

The above techniques can be combined, for example change the constructor

Helper() : vec(CreateYourVector()) {};

These techniques can also be mixed with others, such as the singleton pattern.

In c++11 , you can use the initial list to define a const vector . I think it is a easiest way. Try it: const vector<double> = {1.0, 2.0, 3.0}; . It will not take many lines of code to set the value. I hope this can help you.

The traditional approach would be to only expose a handle that enforces constness and avoids making expensive copies outside the context where the vector is created and initialized. Such handle would be a const pointer or reference.

Since you are using std::vector you can benefit from modern c++ facilities, since std::vector supports features like move semantics off-the-shelf.

In particular, I suggest you to budget some time to have a look at:

  • move semantics
  • smart pointers

which upgrade the traditional way of passing around raw pointers. They enforce ownership semantics (which context owns the object) and allow you to express your intentions in a very precise way through the code.

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