达内C 详解
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
– malloc/free
• new和malloc的不同
– new在分配空间后会比malloc多做三件事
• 如果对象成员又是对象,自动构造此对象 • 自动调用构造函数 • 自动处理类型转换
• delete和free的区别
– delete在释放对象之前会调用析构函数
&结构类型名::成员
• 声明成员指针变量
成员类型 结构类型名::*指针变量名 结构变量.*指针变量名 结构地址->*指针变量名
• 通过成员指针访问结构成员
C++之父给C程序员的建议
• 在C++中几乎不需要用宏
– 用const 或 enum定义明显的常量,用inline避免函数调用的额外 开销,用模板去刻画一族函数或类型,用namespace去避免命名 冲突
– 支持面向对象 – 支持泛型编程 – 支持异常 – 运算符重载等
第一个C++程序
/*the first C++ program*/ #include <iostream> using namespace std; //main function int main() { cout << "Hello world!" << endl; cout << "This is my first C++ program.\n"; }
C++的内存分配
• new/delete
int* p2 = new int;//不保证是零 int* p3 = new int(100); int* p4 = new int[5]; delete p2; delete p3; delete[] p4; char buf[100] = {}; new(buf) int[25]; – 不存在定位分配所对应的delete运算,一旦buf释放, new所分配的空间也随即释放
面向对象编程
面向对象编程
• 万物皆对象 • 程序就是一组对象,对象之间通过发送消 息互相通知做什么 • 每一个对象都有它自己的由其他对象构成 的存储区 • 每一个对象有一个类型 • 一个特定类型的所有对象都能接收相同的 消息
类
• 类是用户定义的数据类型 • 在类中声明的变量和函数称为类的成员
– 变量称为数据成员(也叫成员变量) – 函数称为成员函数(有时称为方法)
union{
}; x = 100;
int x; char c[4];
• C++的枚举不再是普通的整数类型,而是一种 独立的类型,这个体现了C++强类型的特征
C++的布尔类型bool
• c99的bool是一种宏定义,而在c++中则是专门的一种数据类 型bool • bool的值一般为true(逻辑真)和false(逻辑假) • 和c一样,bool值本质上也是整数,true等于1,false等于0 • 另外,可以将任何值赋值给bool类型的变量
• 一个对象的创建过程:
• 默认的空参构造函数
– 分配内存空间 – 初始化成员变量,如果成员是对象,构造他 – 调用构造函数
构造函数的使用
• 构造函数重载
– 构造函数也是函数,拥有重载的特征 – 重载的构造函数在构造对象时根据参数自动选择ቤተ መጻሕፍቲ ባይዱ
– 构造函数也拥有函数参数默认值的特性 – 使用默认值可以减少构造函数的个数 – 初始化列表可以让构造函数在调用之前进行初始化工作 – 如果类的成员变量是const或引用类型,使用初始化列表是 不二选择 – 请试着将写的类分成头文件和实现两部分
• 使用某个名字空间下的对象或函数:
– namespace-name::member-name – ::为域运算符,在此表名一种限定,一个范围
定义命名空间
• 一个名字空间的成员必须采用如下的记法形式引入:
namespace namespace-name{
}
//声明和定义
• 我们不能在名字空间定义之外用加限定的语法形式为名字空间 引入新成员 • 新成员的声明和定义是可以分开的 • 声明和定义分开后,编译器可以帮助捕捉到例如拼写或类型不 匹配一类的错误。 • 一个名字空间也是一个作用域,一个程序越大,通过名字空间 去描述其中逻辑上独立的各个部分也就越重要。 • 理想情况是,程序里的每个实体都属于某个可以识别的逻辑单 位(模块),所以,一个非凡的程序里的每个声明都应该位于某个 名字空间里,以此指明它在程序中所扮演的角色。
尽量少用数组和c风格的字符串标准库中的string和vector可以简化程序更加重要的是试着将程序考虑为一组由类和对象表示的相互作用的概念而不是一堆数据结构和一些可以拨弄的二进制?????面向对象编程面向对象编程?万物皆对象?程序就是一组对象对象之间通过发送消息互相通知做什么?每一个对象都有它自己的由其他对象构成的存储区?每一个对象有一个类型?一个特定类型的所有对象都能接收相同的消息类?类是用户定义的数据类型?在类中声明的变量和函数称为类的成员变量称为数据成员也叫成员变量函数称为成员函数有时称为方法?可以用类来声明变量也称为实例
C++运算符转换
• C++中的运算符,可以用其他关键字转换
x>0 && y>0 可以写成x>0 and y>0
• 下图为可以转换的列表
C++中的函数
• 函数的参数表严格匹配,空参代表没有任何参数,void形参依 然可以使用 • 不再支持C语言中的隐式声明方式,函数调用前必需先声明或 定义 • 函数的返回类型int不能省略 • 函数可以重载
– 以下4个值为false :
• 0 • • • • bool b = 1; b = true; b = 3.14; b = “abcdef”
isLeap = true; int days = 28 + isLeap;//2月份的天数
‘\0’ NULL false
– 其他一切值如果赋值给bool类型的变量都视为true
析构函数
与类名同,但名称前有一个~ 一个类只有一个析构 析构没有参数,没有返回值 在一个对象释放前调用。释放可能是主动的, 也可能是被动的。 • 一个对象的析构函数只调用一次,但语法上允 许多次调用 • 默认析构函数 • • • •
– 何时需要自定义析构呢?
堆中构造和释放对象
• new/delete构造和释放对象 • 使用C风格分配空间构造对象
• 宏在C++中不提倡使用
– 宏存在着一些潜在的危险 – C++中的面向对象不允许预处理器访问类的成员 数据。也意味着宏函数不能用作类的成员函数。
• 内联函数保持了函数的所有特点,但在需要的 地方会像宏一样展开,不需要调用函数的开销。 • 类中直接定义的函数自动被处理成内联函数, 所以一般把内联函数放在头文件中。 • inline是一种请求,实现方式取决于编译器, 特别是当函数较大或是递归的时候。
• 定位分配
C++的引用 reference
• 引用是另外一个变量的别名 • 引用的声明 • 引用必须初始化,且必须用变量初始化。 • 不可能有空引用,必须确保引用和一块合法的存储单元 关联 • 当一个引用被初始化为指向一个对象,它就不能改变为 指向另一个对象 • 引用是用指针来实现的
– 不能写:int& a = 10 – 可以写成const int& a = 10;//常量引用 int iVal; int & iRef = iVal;
• 可以用类来声明变量(也称为实例)。每个实 例是类的一个对象 • 定义类的实例可以称为类的实例化
定义类
• 用struct定义类
– 成员默认为公开
• 用class定义类
– 成员默认为私有
• 类中成员的作用域
– private – protected – public
构造并使用对象
• 定义类Time并使用
第一个C++程序和第一个C程序的不同
• 可以选用g++编译器 • 源文件扩展名可以是.cpp .cc .C .cxx等 • 不再使用c中的头文件
– 如果要用,可以在c头文件名前加c
• #include <cxxxx>
• 不再使用scanf/printf而是cin/cout • 标准的C++头文件不再以.h结尾
– 成员变量 时分秒 – 成员函数 显示 滴答 …
• 使用标准库中的类string构造对象
– = += + > >= < <= == != – size() length() find() str[i] s.c_str(转换成c 风格,返回char*) – 其他成员函数
构造函数
• 构造函数
– – – – 和类名相同 没有返回值类型 只在建立对象的时候被自动调用一次 调用构造函数的主要目的是初始化对象
Tar na
C++语言
从C到C++
C++简介
• 80年代初由贝尔实验室的Bjarne Stroustrup设计和实现 • 1983年被正式命名为C++ • 1998年ANSI/ISO制定了C++国际标准 • 2003年推出了修定版本 • C++一直在发展变化中…
C++和C
• C++包含整个C,C是建立C++的基础 • C++是强类型语言,对类型检查严格 • C++比C更丰富
const对象和const成员函数
• 成员函数可以声明成const函数(声明后加 const) • 对于const对象,只能调用const成员函数 • Const函数和非const函数可以形成重载 • 对于非const对象的函数调用优先选择非 const成员函数 • 对于类中的mutable数据成员,可以被 const成员函数修改
– 转换时做静态检查,即在编译时进行 – void*到其他指针的转换
• reinterpect_cast<类型>() • const_cast<类型>()
– 去掉cv限制
– 动态转换
– 允许强转任何类型的指针 – 把整数强转成指针,指针强转成整数
• dynamic_cast<类型>()
成员指针
• 成员指针是一种相对地址 • 结构体中的成员(包括变量和函数)的相对地 址获取方式
– 在同一作用域中,函数名相同,参数列表不同的函数可以存在若 干个,其返回值任意 – 当出现重载函数时,使用函数指针显得有点问题,当给函数指针 赋值时,指针的类型代表着具体的函数。 – 函数重载的实现是基于函数名的编译时改变 – 当程序跨越编译器或由其它语言调用重载函数时,函数名在编译 时编译器不能对其改变,否则无法调用 – extern “C” 可以告诉编译器,像C语言那样进行编译处理。
在C++中要使用命名空间
• 命名空间也称名字空间,即namespace
– 名字空间是一种描述逻辑分组的机制,如果一些声 明按照某种准则在逻辑上属于同一集团,就可以将 它们放入同一个名字空间,以表明这个事实。 – 防止命名冲突也是一个很重要的原因。一个人写的 程序放到一个名字空间中也是一种可取的做法。
在函数参数和返回值上的引用
• • • • • • 函数的形参可以是引用类型 通过引用传递参数,称之为引用传递 用const来保护引用参数的传递 尽量使用引用传递参数 尽量使用引用代替指针 永远不要返回对局部变量的引用,除非局 部变量是静态的或是在动态内存中分配的
C++中的类型转换运算符
• static_cast<类型>()
使用命名空间
• 带限定词的名字。如果使用另外一个名字 空间中的成员,需要加限定词,如:std::in • 使用声明:using std::in • 使用指令:using namespace std; • 无名名字空间
– 无名名字空间中的成员可以直接使用::访问
C++中的结构、联合和枚举
• C中的结构、联合和枚举类型名包含 struct,union,enum,而C++则不 • C++的结构中可以有函数,称为成员函数 • C++的匿名联合
• 利用参数默认值简化构造函数 • 构造函数的初始化列表
• 实践中,类的声明和定义是分开的
调用对象的成员函数与this指针
• • • • • 一个对象占多大空间呢? 成员函数保存在哪儿? 调用成员函数时,会自动传this指针 this指针是指向当前对象的指针 在成员函数中,可以将this指针当参数传递 ,也可以返回this指针,或返回通过this指 针拿到的对象
• 不要在你需要变量之前去声明,以保证你能立即对它进行初始 化。 • 不要用malloc,new运算会做的更好 • 避免使用void*、指针算术、联合和强制,大多数情况下,强制 都是设计错误的指示器。 • 尽量少用数组和C风格的字符串,标准库中的string和vector可 以简化程序 • 更加重要的是,试着将程序考虑为一组由类和对象表示的相互 作用的概念,而不是一堆数据结构和一些可以拨弄的二进制
函数参数的哑元和默认值
– 哑元是一种没有参数名的参数,主要是为了函 数间的区别以及向前兼容
• 函数的参数可以指定默认值,当调用时没 有传参,就以默认值进行函数调用。 • 有默认值的形参必须靠右,声函数的参数 支持哑元 • 明和定义分开时,默认值必需在声明中指 定,定义中不再指定。
C++中的内联函数
• new和malloc的不同
– new在分配空间后会比malloc多做三件事
• 如果对象成员又是对象,自动构造此对象 • 自动调用构造函数 • 自动处理类型转换
• delete和free的区别
– delete在释放对象之前会调用析构函数
&结构类型名::成员
• 声明成员指针变量
成员类型 结构类型名::*指针变量名 结构变量.*指针变量名 结构地址->*指针变量名
• 通过成员指针访问结构成员
C++之父给C程序员的建议
• 在C++中几乎不需要用宏
– 用const 或 enum定义明显的常量,用inline避免函数调用的额外 开销,用模板去刻画一族函数或类型,用namespace去避免命名 冲突
– 支持面向对象 – 支持泛型编程 – 支持异常 – 运算符重载等
第一个C++程序
/*the first C++ program*/ #include <iostream> using namespace std; //main function int main() { cout << "Hello world!" << endl; cout << "This is my first C++ program.\n"; }
C++的内存分配
• new/delete
int* p2 = new int;//不保证是零 int* p3 = new int(100); int* p4 = new int[5]; delete p2; delete p3; delete[] p4; char buf[100] = {}; new(buf) int[25]; – 不存在定位分配所对应的delete运算,一旦buf释放, new所分配的空间也随即释放
面向对象编程
面向对象编程
• 万物皆对象 • 程序就是一组对象,对象之间通过发送消 息互相通知做什么 • 每一个对象都有它自己的由其他对象构成 的存储区 • 每一个对象有一个类型 • 一个特定类型的所有对象都能接收相同的 消息
类
• 类是用户定义的数据类型 • 在类中声明的变量和函数称为类的成员
– 变量称为数据成员(也叫成员变量) – 函数称为成员函数(有时称为方法)
union{
}; x = 100;
int x; char c[4];
• C++的枚举不再是普通的整数类型,而是一种 独立的类型,这个体现了C++强类型的特征
C++的布尔类型bool
• c99的bool是一种宏定义,而在c++中则是专门的一种数据类 型bool • bool的值一般为true(逻辑真)和false(逻辑假) • 和c一样,bool值本质上也是整数,true等于1,false等于0 • 另外,可以将任何值赋值给bool类型的变量
• 一个对象的创建过程:
• 默认的空参构造函数
– 分配内存空间 – 初始化成员变量,如果成员是对象,构造他 – 调用构造函数
构造函数的使用
• 构造函数重载
– 构造函数也是函数,拥有重载的特征 – 重载的构造函数在构造对象时根据参数自动选择ቤተ መጻሕፍቲ ባይዱ
– 构造函数也拥有函数参数默认值的特性 – 使用默认值可以减少构造函数的个数 – 初始化列表可以让构造函数在调用之前进行初始化工作 – 如果类的成员变量是const或引用类型,使用初始化列表是 不二选择 – 请试着将写的类分成头文件和实现两部分
• 使用某个名字空间下的对象或函数:
– namespace-name::member-name – ::为域运算符,在此表名一种限定,一个范围
定义命名空间
• 一个名字空间的成员必须采用如下的记法形式引入:
namespace namespace-name{
}
//声明和定义
• 我们不能在名字空间定义之外用加限定的语法形式为名字空间 引入新成员 • 新成员的声明和定义是可以分开的 • 声明和定义分开后,编译器可以帮助捕捉到例如拼写或类型不 匹配一类的错误。 • 一个名字空间也是一个作用域,一个程序越大,通过名字空间 去描述其中逻辑上独立的各个部分也就越重要。 • 理想情况是,程序里的每个实体都属于某个可以识别的逻辑单 位(模块),所以,一个非凡的程序里的每个声明都应该位于某个 名字空间里,以此指明它在程序中所扮演的角色。
尽量少用数组和c风格的字符串标准库中的string和vector可以简化程序更加重要的是试着将程序考虑为一组由类和对象表示的相互作用的概念而不是一堆数据结构和一些可以拨弄的二进制?????面向对象编程面向对象编程?万物皆对象?程序就是一组对象对象之间通过发送消息互相通知做什么?每一个对象都有它自己的由其他对象构成的存储区?每一个对象有一个类型?一个特定类型的所有对象都能接收相同的消息类?类是用户定义的数据类型?在类中声明的变量和函数称为类的成员变量称为数据成员也叫成员变量函数称为成员函数有时称为方法?可以用类来声明变量也称为实例
C++运算符转换
• C++中的运算符,可以用其他关键字转换
x>0 && y>0 可以写成x>0 and y>0
• 下图为可以转换的列表
C++中的函数
• 函数的参数表严格匹配,空参代表没有任何参数,void形参依 然可以使用 • 不再支持C语言中的隐式声明方式,函数调用前必需先声明或 定义 • 函数的返回类型int不能省略 • 函数可以重载
– 以下4个值为false :
• 0 • • • • bool b = 1; b = true; b = 3.14; b = “abcdef”
isLeap = true; int days = 28 + isLeap;//2月份的天数
‘\0’ NULL false
– 其他一切值如果赋值给bool类型的变量都视为true
析构函数
与类名同,但名称前有一个~ 一个类只有一个析构 析构没有参数,没有返回值 在一个对象释放前调用。释放可能是主动的, 也可能是被动的。 • 一个对象的析构函数只调用一次,但语法上允 许多次调用 • 默认析构函数 • • • •
– 何时需要自定义析构呢?
堆中构造和释放对象
• new/delete构造和释放对象 • 使用C风格分配空间构造对象
• 宏在C++中不提倡使用
– 宏存在着一些潜在的危险 – C++中的面向对象不允许预处理器访问类的成员 数据。也意味着宏函数不能用作类的成员函数。
• 内联函数保持了函数的所有特点,但在需要的 地方会像宏一样展开,不需要调用函数的开销。 • 类中直接定义的函数自动被处理成内联函数, 所以一般把内联函数放在头文件中。 • inline是一种请求,实现方式取决于编译器, 特别是当函数较大或是递归的时候。
• 定位分配
C++的引用 reference
• 引用是另外一个变量的别名 • 引用的声明 • 引用必须初始化,且必须用变量初始化。 • 不可能有空引用,必须确保引用和一块合法的存储单元 关联 • 当一个引用被初始化为指向一个对象,它就不能改变为 指向另一个对象 • 引用是用指针来实现的
– 不能写:int& a = 10 – 可以写成const int& a = 10;//常量引用 int iVal; int & iRef = iVal;
• 可以用类来声明变量(也称为实例)。每个实 例是类的一个对象 • 定义类的实例可以称为类的实例化
定义类
• 用struct定义类
– 成员默认为公开
• 用class定义类
– 成员默认为私有
• 类中成员的作用域
– private – protected – public
构造并使用对象
• 定义类Time并使用
第一个C++程序和第一个C程序的不同
• 可以选用g++编译器 • 源文件扩展名可以是.cpp .cc .C .cxx等 • 不再使用c中的头文件
– 如果要用,可以在c头文件名前加c
• #include <cxxxx>
• 不再使用scanf/printf而是cin/cout • 标准的C++头文件不再以.h结尾
– 成员变量 时分秒 – 成员函数 显示 滴答 …
• 使用标准库中的类string构造对象
– = += + > >= < <= == != – size() length() find() str[i] s.c_str(转换成c 风格,返回char*) – 其他成员函数
构造函数
• 构造函数
– – – – 和类名相同 没有返回值类型 只在建立对象的时候被自动调用一次 调用构造函数的主要目的是初始化对象
Tar na
C++语言
从C到C++
C++简介
• 80年代初由贝尔实验室的Bjarne Stroustrup设计和实现 • 1983年被正式命名为C++ • 1998年ANSI/ISO制定了C++国际标准 • 2003年推出了修定版本 • C++一直在发展变化中…
C++和C
• C++包含整个C,C是建立C++的基础 • C++是强类型语言,对类型检查严格 • C++比C更丰富
const对象和const成员函数
• 成员函数可以声明成const函数(声明后加 const) • 对于const对象,只能调用const成员函数 • Const函数和非const函数可以形成重载 • 对于非const对象的函数调用优先选择非 const成员函数 • 对于类中的mutable数据成员,可以被 const成员函数修改
– 转换时做静态检查,即在编译时进行 – void*到其他指针的转换
• reinterpect_cast<类型>() • const_cast<类型>()
– 去掉cv限制
– 动态转换
– 允许强转任何类型的指针 – 把整数强转成指针,指针强转成整数
• dynamic_cast<类型>()
成员指针
• 成员指针是一种相对地址 • 结构体中的成员(包括变量和函数)的相对地 址获取方式
– 在同一作用域中,函数名相同,参数列表不同的函数可以存在若 干个,其返回值任意 – 当出现重载函数时,使用函数指针显得有点问题,当给函数指针 赋值时,指针的类型代表着具体的函数。 – 函数重载的实现是基于函数名的编译时改变 – 当程序跨越编译器或由其它语言调用重载函数时,函数名在编译 时编译器不能对其改变,否则无法调用 – extern “C” 可以告诉编译器,像C语言那样进行编译处理。
在C++中要使用命名空间
• 命名空间也称名字空间,即namespace
– 名字空间是一种描述逻辑分组的机制,如果一些声 明按照某种准则在逻辑上属于同一集团,就可以将 它们放入同一个名字空间,以表明这个事实。 – 防止命名冲突也是一个很重要的原因。一个人写的 程序放到一个名字空间中也是一种可取的做法。
在函数参数和返回值上的引用
• • • • • • 函数的形参可以是引用类型 通过引用传递参数,称之为引用传递 用const来保护引用参数的传递 尽量使用引用传递参数 尽量使用引用代替指针 永远不要返回对局部变量的引用,除非局 部变量是静态的或是在动态内存中分配的
C++中的类型转换运算符
• static_cast<类型>()
使用命名空间
• 带限定词的名字。如果使用另外一个名字 空间中的成员,需要加限定词,如:std::in • 使用声明:using std::in • 使用指令:using namespace std; • 无名名字空间
– 无名名字空间中的成员可以直接使用::访问
C++中的结构、联合和枚举
• C中的结构、联合和枚举类型名包含 struct,union,enum,而C++则不 • C++的结构中可以有函数,称为成员函数 • C++的匿名联合
• 利用参数默认值简化构造函数 • 构造函数的初始化列表
• 实践中,类的声明和定义是分开的
调用对象的成员函数与this指针
• • • • • 一个对象占多大空间呢? 成员函数保存在哪儿? 调用成员函数时,会自动传this指针 this指针是指向当前对象的指针 在成员函数中,可以将this指针当参数传递 ,也可以返回this指针,或返回通过this指 针拿到的对象
• 不要在你需要变量之前去声明,以保证你能立即对它进行初始 化。 • 不要用malloc,new运算会做的更好 • 避免使用void*、指针算术、联合和强制,大多数情况下,强制 都是设计错误的指示器。 • 尽量少用数组和C风格的字符串,标准库中的string和vector可 以简化程序 • 更加重要的是,试着将程序考虑为一组由类和对象表示的相互 作用的概念,而不是一堆数据结构和一些可以拨弄的二进制
函数参数的哑元和默认值
– 哑元是一种没有参数名的参数,主要是为了函 数间的区别以及向前兼容
• 函数的参数可以指定默认值,当调用时没 有传参,就以默认值进行函数调用。 • 有默认值的形参必须靠右,声函数的参数 支持哑元 • 明和定义分开时,默认值必需在声明中指 定,定义中不再指定。
C++中的内联函数