简体   繁体   English

无需在C ++中复制即可使变量不可更改

[英]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. 我正在编写一些代码,在这些代码中,在指定值之前声明了std::vector<double>类型的变量。 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 . 但是,它不能声明为const

One way is to create another variable which is const and copy the value into it. 一种方法是创建另一个const变量并将值复制到其中。 const std::vector<double> a(b); would do, and use a instead of b in the program. 会这样做,并在程序中使用a而不是b 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 . 在最坏的情况下,你有一个move at best you have (N)RVO (return value optimization). 充其量你有(N)RVO(返回值优化)。

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. 构建 vector的范围内,它在逻辑上不是const变量。 Once you have built it, you want it not to be changed anymore. 一旦你构建它,你希望它不再被改变。 So you may want to refer to it through a const & . 所以你可能想通过const &引用它。

I'd go this way: 我会这样走:

  • define a function std::vector<double> build_up() 定义函数std::vector<double> build_up()
  • inside build_up , you define a non-const vector and you can build it build_up ,你定义了一个非const vector ,你可以构建它
  • when you're done, you can return it by value ( RVO will avoid any copy) 当你完成后,你可以按值返回( RVO将避免任何副本)
  • refer to the object returned by build_up() as a const object build_up()返回的对象称为const对象

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 另一个(技术上是一种变体)是创建一个包含vector的辅助类,并在构造函数中完成所有工作

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 . c++11 ,您可以使用initial list来定义const vector I think it is a easiest way. 我认为这是最简单的方法。 Try it: const vector<double> = {1.0, 2.0, 3.0}; 试一试: 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. 传统的方法是仅公开一个强制执行const的句柄,并避免在创建和初始化向量的上下文之外制作昂贵的副本。 Such handle would be a const pointer or reference. 这样的句柄将是一个const指针或引用。

Since you are using std::vector you can benefit from modern c++ facilities, since std::vector supports features like move semantics off-the-shelf. 由于你使用的是std::vector你可以从现代的c ++工具中受益,因为std::vector支持像现成的移动语义这样的功能。

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. 它们强制执行所有权语义(该上下文拥有该​​对象),并允许您通过代码以非常精确的方式表达您的意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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