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 没有太多不同,不同的地方在于自定义的类型,而且这种不同比较容易让人混淆:
-
对于基础类型,右值是不可被修改的(non-modifiable),也不可被 const, volatile 所修饰(cv-qualitification ignored)
-
对于自定义的类型(user-defined types),右值却允许通过它的成员函数进行修改。
对于 1),这和 c 是一致的,2) 却是 C++ 中所独有, 因此,如果你看到 C++ 中如下的写法,千万不要惊讶:
https://www.cnblogs.com/catch/p/5019402.html
https://www.cnblogs.com/catch/p/3500678.html