先看代码

#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. Csharp随机生成序列码的方式Guid方法

    主要用于邮箱激活,加密等用处 Guid.NewGuid().ToString()得几种格式显示 .Guid.NewGuid().ToString("N") 结果为: 38bddf4 ...

  2. Linux一些最基础操作

    最后更新时间: 2015-05-06 这是一篇很早之前写的,整理笔记的时候看到了,Linux 非常基础操作. bin/sbin: 一般是存放可以执行文件 绝对路径 相对路径 mkdir dir ls: ...

  3. 关于Java协变性的思考

    简而言之,如果A IS-A B,那么A[] IS-A B[]. 举例:现在有类型Person.Employee和Student.Employee 是一个(IS-A) Person,Student是一个 ...

  4. 项目一、ajax上传数据(显示进度条)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. java虚拟机规范-加载、链接与初始化

    前言 java虚拟机是java跨平台的基石,本文的描述以jdk7.0为准,其他版本可能会有一些微调.java代码本身并不能为jvm识别,实际上在jvm中的表现形式为Class对象,一个java类从字节 ...

  6. Git 创建版本库并实现本地上传数据到GitHub库

    版本库又叫做仓库,其实也是一个目录,这个目录里的所有文件都是被Git管理着,对每个文件的修改,删除,Git都会进行记录,方便我们对其进行跟踪. 因为本地是window环境,我们先从官网下载好windo ...

  7. fedora禁用(开机启动)服务和进程管理

    首先要查看有哪些(开机启动)服务 chkconfig --list 或者: systemctl list-units 然后, 根据需要进行禁用服务的开机启动: chkconfig service_na ...

  8. 1 基础架构:一条sql查询语句如何执行?

    1 基础架构:一条sql查询语句如何执行? 分析一个最简单的查询 mysql> select * from T where ID=10: MySQL基本架构示意图 大体来说,mysql可以分为s ...

  9. IDEA基本设置和快捷键大全

    # IDEA基本设置 ## 设置编码格式 1. Configure - Settings - Editor - File Encodings 2. 将三个编码全部设置为UTF-8 ## 启用Ctrl+ ...

  10. Java ——方法

    本节重点思维导图  方法的定义 例题:1!+2!+3!+4!+…..+15!=? public class Demo { public static void main(String[] args) ...