先看代码

#include "pch.h"
#include <iostream>
#include <string>
using namespace std; template <typename elemType>
class MyArray
{
public:
MyArray(int capacity);
MyArray(const MyArray<elemType>& arr);
~MyArray();
elemType& operator[](int index);
MyArray<elemType> operator=(const MyArray<elemType>& arr);
void PushBack(elemType& data);
int GetSize() const { return this->mSize; }
//void PushBack(T&& data);
private:
int mCapacity;
int mSize;
elemType *pAddr;
}; template <typename elemType>
MyArray<elemType>::MyArray(int capacity)
{
this->mCapacity = capacity;
this->mSize = 0;
this->pAddr = new elemType[this->mCapacity];
} template <typename elemType>
elemType& MyArray<elemType>::operator[](int index)
{
if (index > this->mCapacity || index < 0)
{
//异常
}
else
{
return *(this->pAddr + index);
}
} template<typename elemType>
void MyArray<elemType>::PushBack(elemType& data)
{
if (this->mSize >= this->mCapacity)
{
//异常
return;
}
else
{
*(this->pAddr + this->mSize) = data;
this->mSize++;
}
} template<typename elemType>
MyArray<elemType>::MyArray(const MyArray<elemType>& arr)
{
this->mCapacity = arr.mCapacity;
this->mSize = arr.mSize;
//申请内存空间
this->pAddr = new elemType[this->mCapacity];
//数据拷贝
for (int ix = 0; ix < this->mSize; ++ix)
{
this->pAddr[ix] = arr.pAddr[ix];
}
} template<typename elemType>
MyArray<elemType>::~MyArray()
{
if (this->pAddr != NULL)
{
delete[] this->pAddr;
}
} template<typename elemType>
MyArray<elemType> MyArray<elemType>::operator=(const MyArray<elemType>& arr)
{
if (this->pAddr != NULL)
{
delete[] this->pAddr;
}
this->mCapacity = arr.mCapacity;
this->mSize = arr.mSize;
//申请内存空间
this->pAddr = new elemType[this->mCapacity];
//数据拷贝
for (int ix = 0; ix < this->mSize; ++ix)
{
this->pAddr[ix] = arr.pAddr[ix];
}
return *this;
} void test01()
{
MyArray<int> marray(20);
int a = 10;
int b = 20;
int c = 30;
int d = 40;
marray.PushBack(a);
marray.PushBack(b);
marray.PushBack(c);
marray.PushBack(d);
marray.PushBack(100);
marray.PushBack(200); for (int ix = 0; ix < marray.GetSize(); ++ix)
{
cout << marray[ix] << " ";
}
} int main()
{
test01();
return 0;
}

代码模拟了STL中的array容器,编译代码,报错



报错的代码为

	marray.PushBack(100);
marray.PushBack(200);

PushBack()的实现如下

template<typename elemType>
void MyArray<elemType>::PushBack(elemType& data)
{
if (this->mSize >= this->mCapacity)
{
//异常
return;
}
else
{
*(this->pAddr + this->mSize) = data;
this->mSize++;
}
}

其参数为引用,不能对右值取引用,也就是说

int i = &42;

这行代码是错误的。

	//不能对右值取引用
//左值 可以在多行使用
//右值 即临时变量,只能在当前行使用
marray.PushBack(100);
marray.PushBack(200);

解决办法:重载PushBack()函数

template<typename elemType>
void MyArray<elemType>::PushBack(elemType && data)
{
if (this->mSize >= this->mCapacity)
{
//异常
return;
}
else
{
*(this->pAddr + this->mSize) = data;
this->mSize++;
}
}

另:

在VS2017开发环境中,将PushBack()的函数实现如下

void PushBack(const elemType& data);    //类内声明

template<typename elemType>  //类外实现
void MyArray<elemType>::PushBack(const elemType& data)
{
if (this->mSize >= this->mCapacity)
{
//异常
return;
}
else
{
*(this->pAddr + this->mSize) = data;
this->mSize++;
}
}

这样在使用PushBack()时,编译不会报错

	marray.PushBack(100);
marray.PushBack(200);

但在Linux下,gcc版本为4.4.6,即便是写为

void PushBack(const elemType& data);    //类内声明

编译器仍旧会报错。

C++11的新特性:右值引用的更多相关文章

  1. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  2. C++11 标准新特性: 右值引用与转移语义

    文章出处:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) ...

  3. C++ 新特性-右值引用

    作为最重要的一项语言特性,右值引用(rvalue references)被引入到 C++0x中.我们可以通过操作符“&&”来声明一个右值引用,原先在C++中使用“&”操作符声明 ...

  4. [转][c++11]我理解的右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  5. C++11特性-右值引用

    什么是左值,什么是右值 常见的误区有 = 左边的是左值,右边的是右值. 左值:具有存储性质的对象,即lvalue对象,是指要实际占用内存空间.有内存地址的那些实体对象,例如:变量(variables) ...

  6. [转载] C++11中的右值引用

    C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...

  7. 详解C++右值引用

    C++0x标准出来很长时间了,引入了很多牛逼的特性[1].其中一个便是右值引用,Thomas Becker的文章[2]很全面的介绍了这个特性,读后有如醍醐灌顶,翻译在此以便深入理解. 目录 概述 mo ...

  8. C++11新特性之0——移动语义、移动构造函数和右值引用

    C++引用现在分为左值引用(能取得其地址)和 右值引用(不能取得其地址).其实很好理解,左值引用中的左值一般指的是出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引 ...

  9. C++11新特性(1) 右值引用

    在C++中,左值(lvalue)是能够获取其地址的一个量.因为常常出如今赋值语句的左边.因此称之为左值.比如一个有名称的变量. 比如: int a=10; //a就是一个左值. 传统的C++引用,都是 ...

  10. C++11新特性之右值引用(&&)、移动语义(move)、完美转换(forward)

    1. 右值引用 个人认为右值引用的目的主要是为了是减少内存拷贝,优化性能. 比如下面的代码: String Fun() { String str = "hello world"; ...

随机推荐

  1. bootstrap动态调用select下拉框

    html代码: <label for="classify" class="col-sm-2 control-label">填报部门:</lab ...

  2. HDU 6592 (LIS+输出字典序最大最小)

    题意:给你一个序列,让你找长度最长的字典序最小和最大的单峰序列,单峰序列就是满足先增后降的序列. 思路:先正着求一遍LIS,再反着求一遍LIS,然后用单调栈来模拟. 求字典序最小的话,首先找到第一个顶 ...

  3. 纯CSS3写一个立方体并在鼠标悬停的时候无限循环旋转

  4. WebSocket知识、轮询、长轮询、长连接

    一.WebSocket理论知识 1.什么是websocket WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消 ...

  5. day57——ajax之初体验

    转行学开发,代码100天——2018-05-12 今天是一个特别的日子——首先是母亲节,在此也祝福亲爱的妈妈健康长寿.其次今天是汶川大地震10周年,10年过去了,经历过苦难的人更加坚毅勇敢地面向未来! ...

  6. day48—JavaScript键盘事件

    转行学开发,代码100天——2018-05-03 今天继续学习JavaScript事件基础之键盘事件. 键盘代号获取 keyCode 键盘事件:onkeydown onkeyup 如通过键盘上下左右按 ...

  7. C++中的通用结构定义,及相应的序列化、反序列化接口

    一个通用的C++结构定义如下: typedef struct tagCommonStruct { long len; void* buff; }CommonStruct_st; 此接口对应的普通序列化 ...

  8. LeetCode——160 Intersection of Two Linked Lists

    题目 Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 Output: ...

  9. Linux 文件创建、插入、替换

    创建文件 touch newfile.txt 插入字符串 echo "aaa" >>/newfile.txt 替换字符串 sed -i "s/aaa/ccc/ ...

  10. tbox新增stackless协程支持

    tbox之前提供的stackfull协程库,虽然切换效率已经非常高了,但是由于每个协程都需要维护一个独立的堆栈, 内存空间利用率不是很高,在并发量非常大的时候,内存使用量会相当大. 之前考虑过采用st ...