C++11

Language Standards Supported by GCC

GCC 4.7及之后的版本才支持C11

  • C89=C90:gcc选项是:-ansi, -std=c90 or -std=iso9899:1990;
    • 带了GNU扩展的:-std=gnu90
  • C94=C95:gcc选项:-std=iso9899:199409
  • C99:gcc选项:-std=c99 or -std=iso9899:1999
    • 未完成C99标准之前,叫做C9X
    • 带了GNU扩展的:-std=gnu99
  • C11:gcc选项是-std=c11 or -std=iso9899:2011
    • 未完成C11标准之前,叫做C1X
    • 带了GNU扩展的:-std=gnu11

注意:GCC/G++默认的-std(即C++语言标准)不是C++11,而是C++98,所以要支持C++11的新特性,需要显式地开启,即添加-std=c++11选项。

C++11

C++的创始人:Bjarne Stroustrup

C++11(即ISO/IEC 14882:2011),是目前的C++编程语言的最新正式标准。它取代了第二版标准(第一版公开于1998年,第二版于2003年更新,分别通称C++98以及C++03,两者差异很小)。新的标准包含核心语言的新机能,而且扩展C++标准程序库。C++11新标准由C++标准委员会于2011年8月12日公布,并于2011年9月出版。此次标准为C++98发布后13年来第一次重大修正。

头文件

C++的头文件很乱,常见的有以下3种样式:

#include <xxxx>
#include <yyy.h>
#include <czzz>

其中,

  • C++标准库的头文件
    • 应该这样引用: #include <xxxx>,如iostream;
    • 尽管仍旧支持iostream.h的方式,但这种做法已经被摒弃,在官方标准中被剔除;
  • C标准库的头文件
    • 这样引用:#include <xxx.h>
    • 也能这样引用:#include <cxxx>,其功能与xxx.h一致,但被纳入了std namespace;
  • 非C/C++标准库的头文件
    • 比如OS或POSIX的头文件,比如pthread.h和unistd.h;
    • 只能按#include <xxx.h>的方式;

特别注意一下string头文件:

C++要兼容C的标准库,而C的标准库里碰巧也已经有一个名字叫做“string.h”的头文件,包含一些常用的C字符串处理函数,比如strcpy、strcmp;

这个string.h头文件跟C++的std::string类半点关系也没有,所以<string>并非<string.h>的“升级版本”,他们是毫无关系的两个头文件;

<string.h>是旧的C 头文件,对应的是基于char*的字符串处理函数;

<cstring>是对应于旧C 头文件的std 版本;

<string>是包装了std 的C++头文件,对应的是新的string类;

智能指针

std::shared_ptr

  • 普通指针到智能指针的转换
	int* iPtr = new int(42);
	shared_ptr<int> p(iPtr);
  • 智能指针到普通指针的转换
	int* pI = p.get();

在C++11中,极力推崇完全替代原生指针。而这里面,原生指针使用到了static_cast,dynamic_cast, const_cast的操作,需要用static_pointer_cast, dynamic_pointer_cast, const_pointer_cast对应操作,而并非使用原来的dynamic_cast等。

Android strong pointer

源码:

android/system/core/libutils/RefBase.cpp
android/system/core/libutils/include/utils/StrongPointer.h

注意:所有使用sp指针的类都必须继承RefBase类(虚继承);

sp类是模板类,通过引用计数的方式管理对象的生命周期,实现对象的自动回收;

示例代码:

class T : public virtual RefBase {
public:
	void a() {}
	// ...
};

sp<T> t = new T();

t->a();			// call T's member function
T* pt = t.get();	// call sp's function

上述示例代码展示了调用模板类成员函数和T类成员函数的差异!

sp vs std::shared_ptr

In the Android implementation of strong pointer, any strong-pointer based object must inherit refbase i.e.

sp<TheClass> theObj // TheClass must inherit from class RefBase

This requirement can be seen in the code for one of sp's methods:

template<typename T> sp<T>& sp<T>::operator =(T* other) {
    if (other != NULL) {
        other->incStrong(this);
    }
    if (mPtr != NULL) {
        mPtr->decStrong(this);
    }
    mPtr = other;
    return *this; 
}

In order for call to incStrong or decStrong to not fail . . . other and mPtr must have inherited RefBase

QUESTION

Why is sp implemented such that the obj that it’s managing is required to be a child of RefBase? There’s not even a way to enforce this requirement at compile-time or even runtime. (Well maybe if(type()...)

ANSWER

It saves a memory allocation. When you write:

std::shared_ptr<Foo> pFoo{new Foo(bar)};

pFoo actually has a pointer to a shared data structure (allocated on the heap), which has the reference counters, and the pointer to the actual Foo object. By making objects be derived from RefBase, you can embed the reference counts in the object itself (saving the additional memory allocation).

Interestingly, with C++11 onwards, you can avoid the additional memory allocation by using std::make_shared<Foo> which will do a single memory allocation and construct the shared data structure and the Foo object in it.

The fact there is no compile time checking of the derivation from RefBase is carelessness. m_ptr should have been declared as RefBase *m_ptr, and then operator * (etc) should have done a static_cast to T*. In fact, I would probably have made sp<T> inherit from sp_base which had the comparison operators as public, and the other functions as protected.

Edit

On second thoughts, there is quite a bit of compile time checking. If T doesn’t have an incStrong member, the compilation will fail, and it almost certainly won’t unless it derives from RefBase. I still think converting a T* to a RefBase* would have been a better check, but the one that is there is probably good enough.

Tips
  • sleep 1秒钟
	#include <thread>
	#include <chrono>
    
    std::this_thread::sleep_for (std::chrono::seconds(1));
  • 线程
    C++11提供了std::thread类,其实就是对pthread的封装;而且在编译时,需要链接pthread库;

  • 其他

参考链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值