【C++】动态内存管理/move/以及移动构造与移动赋值运算符

1 .对象移动与右值引用 实际应用过程中遇到的问题及其解决方案

问题描述:

bool CrossCenters(const cv::Mat& image,
cv::Size& image_size);

/home/sun/orthodox_ws/deptrum/src/pipeline/orthodox_impl.cc:195:54: error: cannot bind non-const lvalue reference of type ‘cv::Size& {aka cv::Size_<int>&}’ to an rvalue of type ‘cv::Size {aka cv::Size_<int>}’
                                          ir_8bit.size(),
                                          ~~~~~~~~~~~~^~

加上const

/home/sun/orthodox_ws/deptrum/orthodox/src/utils/loader.cc: In member function ‘bool deptrum::Loader::CrossCenters(const cv::Mat&, std::vector<cv::Mat>&, const Size&, std::vector<std::vector<cv::Point_<float> > >&, std::vector<std::vector<cv::Point3_<float> > >&, std::vector<deptrum::orthodox::CrossCenter>&, std::vector<cv::Mat>&, cv::Mat&, bool)’:
/home/sun/orthodox_ws/deptrum/orthodox/src/utils/loader.cc:70:27: error: passing ‘const Size {aka const cv::Size_<int>}’ as ‘this’ argument discards qualifiers [-fpermissive]
   image_size = image.size();

bool CrossCenters(const cv::Mat& image, cv::Size& image_size)在接口引用的过程中,如下

  result = CrossCenters(input_gray,
                        input_gray.size())

内部实现:

bool CrossCenters(const cv::Mat& image,
                  cv::Size& image_size) {
。。。。
  image_list.push_back(image);
  image_size = image.size();

分析:

通常情况下,函数f(a),a的值会存在一个临时变量中,当把这个临时变量传给f时候,由于 CrossCenters声明中image_size参数是 cv::Size& ,不是常量引用。因为c++编译器的一个关于语义的限制,如果一个参数以非const引用传入,c++编译器就会认为程序员会在函数中修改这个值,并且这个被修改的值在返回后要发挥作用。但是把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉,所以一般来说,修改一个临时变量是毫无意义的。据此,c++编译器加入了临时变量不能作为非const引用的这个语义限制。

c++中临时变量不能作为非const的引用参数

解决方法参考:

https://www.cnblogs.com/area-h-p/p/11498481.html

2. 动态内存管理类

3. 对象移动与右值引用

int a;
int b;

a = 3;
b = 4;
a = b;
b = a;

// 以下写法不合法。
3 = a;
a+b = 4;

在 c 语言中, 确切地说应该是左值表达式,右值表达式:表达式是有值的,值是有类型的,值是动态的,类型是静态的,这是基本的概念 。通常来说有名字的变量就是左值(如上面例子中的 a, b),而由运算操作(加减乘除,函数调用返回值等)所产生的中间结果(没有名字)就是右值,如上的 3 + 4, a + b 等。我们暂且可以认为:左值就是在程序中能够寻值的东西,右值就是没法取到它的地址的东西(不完全准确),但如上概念到了 c++ 中,就变得稍有不同。具体来说,在 c++ 中,每一个表达式都会产生一个左值,或者右值,相应的,该表达式也就被称作“左值表达式", “右值表达式”。对于基本数据类型来说(primitive types),左值右值的概念和 c 没有太多不同,不同的地方在于自定义的类型,而且这种不同比较容易让人混淆:

  1. 对于基础类型,右值是不可被修改的(non-modifiable),也不可被 const, volatile 所修饰(cv-qualitification ignored)

  2. 对于自定义的类型(user-defined types),右值却允许通过它的成员函数进行修改。

对于 1),这和 c 是一致的,2) 却是 C++ 中所独有, 因此,如果你看到 C++ 中如下的写法,千万不要惊讶:

https://www.cnblogs.com/catch/p/5019402.html

https://www.cnblogs.com/catch/p/3500678.html

4. 移动构造与移动复制运算符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大江东去浪淘尽千古风流人物

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值