先看代码

#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. UITabbarController & UITabbar 学习

    最后更新2016-04-06 一. UITabbarController 给UITabbarController 设置viewControllers熟悉时候,超过五个就会有一个 moreNavigat ...

  2. 170830-关于JdbcTemplate的知识点

    1.Spring提供的一个操作数据库的技术JdbcTemplate,是对Jdbc的封装.语法风格非常接近DBUtils. JdbcTemplate可以直接操作数据库,加快效率,而且学这个JdbcTem ...

  3. 纯css实现Material Design中的水滴动画按钮

    前言 大家平时应该经常见到这种特效,很炫酷不是吗 这是谷歌Material Design中最常见的特效了,市面上也有很多现成的js库,用来模拟这一特效.但是往往要引入一大堆js和css,其实在已有的项 ...

  4. Anyhashable打印格式化

    NSLog("<LocalContactMatch>: \(bestAttemptContent.userInfo as AnyObject)")

  5. edusoho 支持同一账号多人同时登录

    文件: ./src/Topxia/WebBundle/Listener/UserLoginTokenListener.php 函数: public function onGetUserLoginLis ...

  6. an ordered dict within the ordered dict

    w http://stackoverflow.com/questions/20166749/how-to-convert-an-ordereddict-into-a-regular-dict-in-p ...

  7. oracle常用sql语句和函数

    --查询表的字段数 select count(*) from user_tab_columns where table_name = '表名'; --查询数据库用户密码的profile(一般为defa ...

  8. 认识Dow(下)

    节点属性 在文档对象模型 (DOM) 中,每个节点都是一个对象.DOM 节点有三个重要的属性 : 1. nodeName : 节点的名称 2. nodeValue :节点的值 3. nodeType ...

  9. 关于 token

    用户在浏览器做一系列操作,后台服务怎么判断这些操作是来自同一个用户? 1. seesion 用户登录后,后台生成 sessionid 返回给浏览器,浏览器的每次请求带上 sessionid,后台关联 ...

  10. spring boot 1.5.10.RELEASE ,spring boot admin 1.5.7 添加 security

    生产环境的客户端actuator最好是加上security校验,不然配置信息不登录就能直接获取到 server端配置,参考官方 文档,https://codecentric.github.io/spr ...