前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++11基础学习系列三

C++11基础学习系列三

作者头像
吕海峰
发布2018-04-03 15:17:22
7910
发布2018-04-03 15:17:22
举报
文章被收录于专栏:BrianBrian

概述

随着自己学习C++11的进度,今天记录和实战C++11的战果。废话少说,直接记录C++11的点滴。

数组

在前面学习系列里面,介绍了模板容器类vector,是一个单链表。今天来了解一下C++中的数组。数组也是存放相同类型的容器,数组的大小是固定不变的(编译时数组的维度必须是已知的)。如果想动态操作容器(增加,删除等)或者事先不知道容器的大小,请使用vector。 在使用数组时注意一下几点: 1.数组的维度必须是常量表达式,在编译时是已知的。

代码语言:javascript
复制
#错误的,无法通过非常量表达式初始化数组,请使用constexpr.
unsigned int size = 12;
#正确的
constexpr unsigned int size = 12;
#getsize()返回结果必须是常量表达式。
int a[size/getsize()]={1,2,3};

2.数组的类型不能使用auto关键字推断类型。 3.显示初始化数组元素时,可省略数组的维度。

代码语言:javascript
复制
int a[]={1,2,3};
string b[4]={"a","b"};

4.数组时不允许copy和赋值,不能将数组的内容拷贝给其他数组作为初始值,也不能为其他数组赋值。

代码语言:javascript
复制
int a[]={1,2,3};
// 错误的
int b[] = a;
// 错误的
b=a;

5.指针和数组很多细节需要注意,包括通过指针访问数组元素。比如:

代码语言:javascript
复制
// temp是含有10个整形指针的数组
int *temp[10];
// temp是个指针,指向一个含有10个整数的数组。
int (*temp)[10];
// temp引用一个含有10个整数的数组。
int (&temp)[10];
string nums[]={"a","b"};
// 指向数组的首元素的指针
string *p = nums;
// p1的类型是指针类型,指向的是string*
auto(nums) p1;
// p2 是一个字符串数组
decltype(nums) p2 = {"c","d"};
//C++11引入新的标准,来获得数组的首元素地址和末尾元素的下一个位置的地址。
int nums [] = {2,3,4,5};
int *start = begin(nums);
int *last = end(nums);

显示转换

强制类型显示转换有static_cast,dynamic_cast,const_cast和reinterpret_cast.其中dynamic_cast是运行时识别的一种技术,后面会详细介绍。

  • static_cast:任何具有明确定义的类型转换(不包含底层const),比如:数值类型转换,void* 类型的转换。(const int * const a 其中靠近a的为顶层cast,远离a的为底层cast。) int i,j; double k = static_cast<double>(j)/i; void *p = &i; int *t = static_cast<int*>(p);
  • const_cast智能改变运算对象的底层const,它可以去掉底层const的性质。 const string *p; string *q = const_cast(string*)(p);
  • reinterpret_cast为运算对象的位模式提供较低层次上的重新解释,由于是对象的位模式,所以严重依赖硬件的架构。实际运用较少。

函数

再详细讲解C++11函数对象之前,首先要熟悉看一下局部对象,局部对象包括:自动对象和局部静态对象

函数局部对象

局部对象 形参和函数体内定义的变量,局部变量还会隐藏外层作用域的同名对象。在所有函数体之外定义的对象存在于程序的整个执行过程,当程序启动时被创建,知道程序结束时被创建。

  • 自动对象 存在于块执行期间的对象,形参是一种自动对象。如果变量本身含有初始值,就用这个初始值进行初始化;如果不包含初始值,执行默认初始化,内置类型的默认初始化将产生未定义的值。
  • 局部静态对象 通过static将局部对象定义的,执行第一次经过对象定义的语句时初始化,知道程序结束时销毁,内置类型的局部静态变量初始化为0.

函数参数传递

依据形参传递的类型将函数传递,分为按引用传递和按值传递,当形参为引用类型时是按引用传递,实际是传递实参的别名。当实参的值被拷贝给形参时,形参和实参是两个互相独立的对象,这是按值传递。还有一种是指针形参,指针是按值传递的,当执行指针拷贝时,拷贝的是指针的值。所以你可以通过指针来修改实参的值。 由于拷贝大的类型对象或者容器对象比较低效,甚至有的类型(IO类型)是不支持拷贝的,这时我们尽量采用按引用传递,这样可以避免拷贝付出的代价。如果函数内无须改变参数的值时,最好将其声明为常量引用。

const形参和实参

顶层const作用于对象本身。

代码语言:javascript
复制
// 顶层const对象,不能改变a
const int a = 12;
// 当拷贝a时,忽略了顶层const的影响。
int i = a;
// 顶层const对象,不能改变p的值。
int * const p = &i;
// 但可以通过p所指向的地址修改它的value。
*p=12;

当用实参初始化形参时会忽略掉顶层const,形参的顶层const会被忽略掉。

代码语言:javascript
复制
//func既可以接收int,也可以接收const int,但是不能修改i的值。
void func(const int i);

尽量使用常量引用

可变形参的函数

可变形参是通过initializer_list实现,但是要求类型一致。

代码语言:javascript
复制
#include <iostream>

void message(std::initializer_list<std::string> temp){
    for(auto i:temp){
        std::cout << i << std::endl;
    }
}

int main() {
    message({"hello","world","brian"});
    return 0;
}

返回类型

1.不要返回局部对象的引用或者指针 由于局部对象在函数调用完后,局部对象所占用的存储空间随之被释放。 2.引用返回左值 调用一个返回引用的函数得到左值,其它返回类型为右值。

代码语言:javascript
复制
#include <iostream>
char &get_char(std::string & a,std::string::size_type index) {
    return a[index];
}
int main() {
    std::string s="hello";
    get_char(s,2)='E';
    std::cout <<s<< std::endl;
    return 0;
}
# 输出为
hEllo

3.通过列表初始化返回多个值

代码语言:javascript
复制
#include <iostream>
#include <vector>

std::vector<std::string> get_err(){
    return {"hello","error"};
}

int main() {
    auto list = get_err();
    for(auto i : list){
        std::cout << i << std::endl;
    }
    return 0;
}
#输出为
hello
error

4.返回数组的指针 由于数组不能被拷贝,所以函数不能返回数组,但是可以返回数组的指针或引用。 在C语言中通过typedef来重命名一个类型名称,在C++中通过using来,虽然typedef可以在c++继续使用,但是还是建议使用using.

代码语言:javascript
复制
typedef int arr[10]; //arr是类型别名,表示含有10个整数的数组。
等价于
using arr = int[10];
int (*p2)[10] = &arr; //p2是一个指针指向一个含有10个整数的数组

值得注意的是如果要返回数组指针的函数,稍微麻烦一些: Type(*function(parameter_list))[dimension] int(*func(int i))[10],func是一个函数指针,指向一个返回值为10个整数的数组。 由于这样声明太过于麻烦,所以在c++11标准中通过尾置返回类型,任何函数都能使用尾置返回类型。上述的声明可以通过: auto func(int i)->int(*)[10]

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-05-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 数组
  • 显示转换
  • 函数
    • 函数局部对象
      • 函数参数传递
        • const形参和实参
          • 可变形参的函数
            • 返回类型
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档