https://lobin.iteye.com/admin/blogs/2524524
https://www.iteye.com/blog/lobin-2508615
-
第8章 C++ lvalue&rvalue https://lobin.iteye.com/admin/blogs/2537676
-
第9章 C++ 引用 https://lobin.iteye.com/admin/blogs/2537796
-
第10章 C++类型转换 https://lobin.iteye.com/admin/blogs/2537675
-
第18章 C++ 重载 https://lobin.iteye.com/admin/blogs/2537680
-
第19章 C++ 类和对象 https://lobin.iteye.com/admin/blogs/2537679
-
第20章 C++ 继承 https://lobin.iteye.com/admin/blogs/2537677
-
第21章 C++ 虚函数 https://lobin.iteye.com/admin/blogs/2537678
-
第22章 C++ 对象布局 https://lobin.iteye.com/admin/blogs/2537774
-
第23章 C++ 虚表 https://lobin.iteye.com/admin/blogs/2537795
-
第30章 C++ 模板 https://lobin.iteye.com/admin/blogs/2537681
-
第31章 C++ STL https://lobin.iteye.com/admin/blogs/2327681
-
C++ 智能指针 https://lobin.iteye.com/admin/blogs/2327876
-
C++ auto_ptr https://lobin.iteye.com/admin/blogs/2327674
C++继承了C的风格。
C with Class
C程序基本上可以不用修改就可以移植到C++程序中
C++也可以采用C中的编程风格。
C++支持面向对象
C++支持模板编程
C++支持元编程
C++还支持函数式编程
https://www.stroustrup.com
C
C++
从C到C++
https://en.cppreference.com/w/
https://cplusplus.com/reference/
类型
literal type
字面类型可以是void、标量类型、引用类型、数组字面类型、或者满足以下所有性质的class类型:
-它有一个简单的析构函数
-它是一个聚合类型或至少有一个不是复制或移动构造的构造函数或构造函数模板,并且
-其所有的非静态数据成员和基类都是non-volatile(非易失性)的文字类型。
表达式
拷贝
结构体
C++中结构体和C中的结构体还是有本质区别的,基本上已经具备了C++类型的特征。结构体不只可以有成员变量,还可以有成员函数,这个成员函数说的不是C结构体中的函数指针,这本质上还是成员变量,当然C++也可以有函数指针。
C++的结构体支持成员函数。
在结构体的成员函数中可以通过this来获取结构体对象,这在函数指针成员中也是可以的。这在C结构体中是没有的。
可以说,C++中的结构体除了继承方式以及成员访问默认都是public之外(C++中的结构体成员也无法指定是public、protected或者private),其他的基本和C++的类是一样的。
C++中的结构体和联合体定义为“a class defined with the keywords struct or union”,这和类定义为“a class defined with the keyword class”并没有多大差异。
trivially copyable class
trivial class
意思就是trivial class是一个有trivial默认构造函数的类,并且是一个trivially copyable class。
classes.— end note ]
POD struct
data members of type non-POD struct, non-POD union (or array of such types).
意思就是一个POD结构体是一个扁平的类以及标准布局的类,没有非POD结构体以及非POD联合体(包括这种类型的数组)的非静态数据成员。
POD union
is a union that is both a trivial class and a standard layout class, and has no non-static data members of
type non-POD struct, non-POD union (or array of such types).
意思和上面的一样,就是一个POD联合体是一个扁平的类以及标准布局的类,没有非POD结构体以及非POD联合体(包括这种类型的数组)的非静态数据成员。
POD union和POD struct并没有什么区别。
POD class
意思就是一个POD类是一个POD struct或者POD union。
如果我们按照C中的结构体或者联合体来理解POD类的话,POD类感觉和类(class)没什么关系。
移动
template<typename _Tp >
constexpr std::remove_reference<_Tp>::type&& std::move ( _Tp && __t )
constexprnoexcept
Convert a value to an rvalue.
Parameters
__t A thing of arbitrary type.
Returns
The parameter cast to an rvalue-reference to allow moving it.
Definition at line 104 of file move.h.
https://gcc.gnu.org/onlinedocs/gcc-12.1.0/libstdc++/api/a01588.html#ga9f81219bfbfaac50d44f79095a639620
move函数其实是将一个值转换为右值(引用)。
参考c++/v1/type_traits中的代码:
template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename remove_reference<_Tp>::type&& move(_Tp&& __t) _NOEXCEPT { typedef typename remove_reference<_Tp>::type _Up; return static_cast<_Up&&>(__t); }
下面是展开后的代码:
template <class _Tp> inline __attribute__ ((__visibility__("hidden"), __always_inline__)) constexpr typename remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { typedef typename remove_reference<_Tp>::type _Up; return static_cast<_Up&&>(__t); }
remove_reference定义如下:
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference {typedef _Tp type;}; template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&> {typedef _Tp type;}; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY remove_reference<_Tp&&> {typedef _Tp type;}; #endif
int i = 100;
int &&i2 = std::move(i);
template<typename _Tp >
constexpr __conditional_t<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&> std::move_if_noexcept ( _Tp & __x )
constexprnoexcept
Conditionally convert a value to an rvalue.
Parameters
__x A thing of arbitrary type.
Returns
The parameter, possibly cast to an rvalue-reference.
Same as std::move unless the type's move constructor could throw and the type is copyable, in which case an lvalue-reference is returned instead.
Definition at line 125 of file move.h.
https://gcc.gnu.org/onlinedocs/gcc-12.1.0/libstdc++/api/a01588.html#ga0e32868df3e12ec3f230ea28545b6ea8
template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES typename conditional < !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&, _Tp&& >::type #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES const _Tp& #endif move_if_noexcept(_Tp& __x) _NOEXCEPT { return _VSTD::move(__x); }
下面是展开后的代码:
template <class _Tp> inline __attribute__ ((__visibility__("hidden"), __always_inline__)) constexpr typename conditional < !is_nothrow_move_constructible<_Tp>::value && is_copy_constructible<_Tp>::value, const _Tp&, _Tp&& >::type move_if_noexcept(_Tp& __x) noexcept { return std::__1::move(__x); }
forward
参考c++/v1/type_traits中的代码:
template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT { return static_cast<_Tp&&>(__t); }
另一种形式:
template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT { static_assert(!std::is_lvalue_reference<_Tp>::value, "Can not forward an rvalue as an lvalue."); return static_cast<_Tp&&>(__t); }
CV-qualifiers
CV-qualifiers翻译过来的意思就是“CV限定符”。这里的c其实指的就是const,v指的就是volatile。我们在定义变量和函数的时候,可以给变量指定const或者volatile,没有指定const或者volatile的变量类型被称为“cv-unqualified type”,而指定了const或者volatile的变量类型被称为“cv-qualified type”。
根据const或者volatile的限定,每一种“cv-unqualified type”的类型都对应3中“cv-qualified”版本的类型,即const-qualified版本的类型, volatile-qualified版本的类型, 以及const-volatile-qualified版本的类型。它们都属于不同的类型。
cv
an arbitrary set of cv-qualifiers, i.e., one of {const}, {volatile}, {const, volatile}, or the empty set.
Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “cv T,” where
T is an array type, refers to an array whose elements are so-qualified. An array type whose elements are
cv-qualified is also considered to have the same cv-qualifications as its elements. [ Example:
typedef char CA[5];
typedef const char CC;
CC arr1[5] = { 0 };
const CA arr2 = { 0 };
The type of both arr1 and arr2 is “array of 5 const char,” and the array type is considered to be constqualified. — end example ]
Constant expressions
constexpr
constexpr和const都是属于“const-qualified type”类型。
能用const的地方也能用constexpr。
constexpr变量必须初始化为一个常量表达式,即上面的“Constant expressions”。
int a = 10;
constexpr int b = a;
这里的a并不属于常量表达式。
constexpr int a2 = 10;
#define T 10
constexpr int a3 = T;
const int a1 = 10;
constexpr int a5 = a1;
这里的a1属于常量表达式
int a = 10;
const int a1 = a;
constexpr int a5 = a1;
这里的a1不属于常量表达式,因为a不属于常量表达式
const int a1 = 10;
int const a2 = a1;
constexpr int a5 = a2;
这里的a2属于常量表达式。
int a = 10;
const int a1 = a;
int const a2 = a1;
constexpr int a5 = a2;
这里的a2不属于常量表达式,因为a不属于常量表达式
constexpr function
to be a constexpr function. Similarly, a constexpr specifier used in a constructor declaration declares that
constructor to be a constexpr constructor. constexpr functions and constexpr constructors are implicitly
inline (7.1.2).
将一个constexpr函数赋值给一个constexpr变量。
constexpr int square(int x)
{
return x * x;
}
const int a1 = 10;
constexpr int a6 = square(a1);
constexpr constructor
函数
函数的定义
函数的声明
函数的调用
函数定义后,在调用前应该先进行声明
void fx1(); int main() { fx1(); } void fx1() { printf("call fx1\n"); }
在VC下,函数定义后,如果在调用前没有先进行声明,则会报错:
int main() { fx1(); } void fx1() { printf("call fx1\n"); }
注意这个程序虽然是c风格,但这里是c++程序,是cpp文件fntest2.cpp,而不是fntest2.c。
编译
>cl /c fntest2.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for
80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
fntest2.cpp
fntest2.cpp(5) : error C2065: 'fx1' : undeclared identifier
fntest2.cpp(10) : error C2373: 'fx1' : redefinition; different type modifiers
这里和以c程序的方式编译的结果报错有点不一样。
内存分配和回收
new&delete
C++中new&delete指的是什么?
int *a1 = new int(10);
int *a2 = new (std::nothrow) int(10);
int *a3 = new int[10];
C++中new是一种操作符(Operator)。
C++中new是一个表达式。
C++中new表示一些函数,也就是所谓的“allocation function”。
分配内存
C++继承了C语言的特性。也保留了C的malloc、calloc、realloc的动态内存分配的方式。
需要注意的是,malloc、calloc、realloc这几个函数返回的是一个void*指针类型,当我们需要某个类型的一块内存空间时,需要强制转换为指定类型的指针,如char *p = (char *) malloc(1024 * 1024 * 1024);在C语言中,void*指针可以隐式的和其他类型的指针进行转换。但在C++中不支持void*指针和其他类型的指针进行隐式转换,需要进行强制转换。
这种强制转换也可以通过static_cast进行,如下示例:
char *p = static_cast<char *>(malloc(1024 * 1024 * 1024));
C++还支持通过new的方式来为对象分配一块内存。
new-expression
A *a2 = new A("this is a2.");
delete-expression
内存分配和回收函数
即我们说的allocation function和deallocation function,也就是new和delete,这里new和delete指的不是operator,也不是new表达式或者delete表达式。
内存分配和回收函数都有好几种形式,包括new和delete,都有好几种形式。包括简单形式(即单一对象形式)、数组形式、以及Placement形式。
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
这两种形式在程序中可以自定义自己的实现。
这里的“Replaceable”表示在程序中可以自定义以替换C++标准库中默认定义的版本。
_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz) #if !__has_feature(cxx_noexcept) throw(std::bad_alloc) #endif ;
_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;}
C++的这些allocation function和deallocation function,也就是new和delete,这些函数和一般的函数不太一样,函数定义的形式和使用都不一样。这些函数都是些操作符重载函数,new和delete这两个都是操作符。
内存分配失败
先看下通过C的方式分配内存失败的情况
for (int i = 0;;i++) { char *p = (char *) malloc(1024 * 1024 * 1024); if (p == NULL) { printf("malloc err.\n"); return -1; } }
malloc: *** mach_vm_map(size=1073741824) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
malloc err.
实际如果malloc失败的话,你可以看不到这么多错误信息,只能看到自己打印出来的“malloc err.”错误信息。
linkage-specification
for the string-literals "C" and "C++". Use of a string-literal other than "C" or "C++" is conditionallysupported, with implementation-defined semantics. [ Note: Therefore, a linkage-specification with a stringliteral that is unknown to the implementation requires a diagnostic. — end note ] [ Note: It is recommended
that the spelling of the string-literal be taken from the document defining that language. For example, Ada
(not ADA) and Fortran or FORTRAN, depending on the vintage. — end note ]
namespace
std
标准命名空间。
抽象类
含有纯虚函数的类为抽象类。
class A
{
public:
virtual void a() = 0;
};
class B : public A
{
public:
virtual void a()
{
cout<<"B::a()"<<endl;
}
};
int main()
{
A *b1 = new B();
B *b2 = new B();
b1->a();
b2->a();
}
分配内存
栈上分配
堆上分配
释放内存
虚函数表
重载
全局重载
类函数重载
多态
压制多态
C++兼容C的语法,并在C的基础上进行了增强。
内联
offsetof
offsetof这是一个宏函数,并不是标准函数,标准库并不提供这个函数。并不是所有的编译器或者C库都会提供这个函数,Linux下gcc采用的glibc会提供这个函数,MacOS下gcc采用glibc的话也会提供这个函数。clang的话也会有这个函数。通常定义如下。
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
MacOS下(clang)标准库头文件stddef.h定义如下:
#define offsetof(t, d) __builtin_offsetof(t, d)
MacOS下stddef.h的定义是这样的:
在stddef.h头文件中包含了sys/_types.h、sys/_types/_offsetof.h这两个头文件。
sys/_types/_offsetof.h头文件中的定义:
#define offsetof(type, field) __offsetof(type, field)
sys/_types.h头文件中的定义:
#if defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 || __GNUC__ > 3)
#define __offsetof(type, field) __builtin_offsetof(type, field)
#else /* !(gcc >= 3.5) */
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
#endif /* (gcc >= 3.5) */
__builtin_offsetof是编译器内置的函数,也一定是一个宏。这里主要看下面的那个定义:
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
相关推荐
c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++代码c++...
内容包含:C++11 C++14 C++17 C++20 注释 C++ 编译器支持情况表 独立与宿主实现 C++ 语言 C++ 关键词 预处理器 C++ 标准库头文件 具名要求 功能特性测试 (C++20) 工具库 类型支持(基本类型、RTTI、类型特性) 概念...
c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀c++狼人杀...
《C++编程实例100篇》是一本深入浅出的C++编程教程,它以实践为主导,通过丰富的实例帮助学习者掌握C++语言的基础和核心概念。这本书的每个实例都精心设计,旨在帮助初学者和有经验的开发者巩固和提升C++编程技能。 ...
C++面试题笔试题C++ 数据结构算法笔试题资料合集: 50个C、C++面试题.pdf C++ 数据结构、算法笔试题.docx C++基础面试题.docx C++开发工程师面试题库.docx C++技能测试试卷一及答案.docx C++技能测试试卷二及答案....
【标题】:“C++各种小游戏(我们老师的)” 在C++编程领域,开发小游戏是一种非常有效的学习实践方式,尤其对于初学者来说。本资源集合包含了我们老师精心制作的一系列C++小游戏,旨在帮助学生深入理解和掌握C++...
华为c++编码规范和安全编码规范最新3.1版本 华为c++编码规范和安全编码规范最新3.1版本 华为c++编码规范和安全编码规范最新3.1版本 华为c++编码规范和安全编码规范最新3.1版本 华为c++编码规范和安全编码规范最新3.1...
Dev C++是一款轻量级的C++集成开发环境(IDE),专为初学者和专业开发者提供简洁、高效的编程环境。这个6.3版本是其历史上的一个重要里程碑,它结合了GCC编译器(GNU Compiler Collection)和一个用户友好的界面,...
C++大作业坦克大战源码C++大作业坦克大战源码C++大作业坦克大战源码C++大作业坦克大战源码C++大作业坦克大战源码。C++大作业坦克大战源码C++大作业坦克大战源码C++大作业坦克大战源码C++大作业坦克大战源码C++大作业...
C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++课程设计C++飞机大战 C++...
c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏c++小游戏...
《计算机科学丛书:C++语言导学》作者是C++语言的设计者和最初实现者,写作本书的目的是让有经验的程序员快速了解C++现代语言。书中几乎介绍了C++语言的全部核心功能和重要的标准库组件,以很短的篇幅将C++语言的...
小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小熊猫devc++下载包小...
C++Builder 6是一款由Borland公司(后被Embarcadero Technologies收购)开发的集成开发环境(IDE),主要用于C++编程语言的应用程序开发。它结合了强大的编译器、调试器、可视化设计工具和其他实用功能,为开发者...
《Visual C++游戏开发经典案例详解》这本书是针对使用Visual C++进行游戏开发的专业指南,旨在帮助读者通过实例学习和掌握C++编程语言在游戏开发中的应用。书中的内容覆盖了从基础到高级的游戏开发技术,包括图形...
C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业飞机大战源码C++大作业...
《Effective Modern C++:改善C++11和C++14的42个具体做法(影印版)(英文版)》中包括以下主题:剖析花括号初始化、noexcept规范、完美转发、智能指针make函数的优缺点;讲解std∷move,std∷forward,rvalue引用和...
C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++
基于C++语言开发的军旗游戏完整源码 基于C++语言开发的军旗游戏完整源码 基于C++语言开发的军旗游戏完整源码 基于C++语言开发的军旗游戏完整源码 基于C++语言开发的军旗游戏完整源码 基于C++语言开发的军旗游戏完整...
21天学通C++(第五版) vs2008程序打包 深入浅出MFC 浙大教材C++达内 C++ 华为C++培训资料 visual c++_MFC 资源内容: visual c++_MFC 达内 C++ C++课件.ppt c++源码 .rar Core C++ Programming_new.ppt Core C++ ...