C++面向对象高级编程笔记02--GeekBand
来源:互联网 发布:网络药店排名 编辑:程序博客网 时间:2024/06/04 18:43
第二个周 01
这节课主要讲了Big Three(拷贝构造,拷贝赋值,析构函数)。
为什么需要这几个特殊函数?这个周要讲的是 class with pointer,在类中成员要使用指针,多半要动态分配内存,考虑下面几种对象的创建和赋值场景
String str1("Hello");
String str2(str1);
String str3 = str1;
String str4 = new String("Hello");
str2和str3,如果不使用拷贝构造和拷贝赋值,则会使用编译器默认的拷贝和赋值,bit by bit的拷贝。最终的结果是浅拷贝,而我们通常要的是深拷贝。
以String为例,
class String {
public:
String(const char* cstr = 0);
String(const String& str); //拷贝构造
String& operator=(const String& str); //拷贝赋值
~String(); //析构函数
char* get_c_str() const { return m_data; }
private:
char* m_data;
};
那为什么要使用析构函数? 因为类中使用了动态内存,需要在析构函数中释放。
相对比,complex类则不需要big three,因为它类中没有使用指针,也就不存在说的这些问题。
对于拷贝赋值,copy assignment operator
inline
String& String::operator =(const String& str) {
if (this == &str) { // 自我赋值检测
return *this;
}
delete[] m_data; // 先delete掉自己
m_data = new char[strlen(str.m_data) + 1)];
strcpy(m_data, str.m_data); // friend
return *this;
}
课程还还提到了自我赋值检测,如果不做的话,一旦拷贝的是自己,不但效率上保证不了,而且会出错。因为delete掉m_data后,new的时候,长度为0;
第二周/10
扩展补充,类模版,函数模版和其他
Ø 静态变量和静态函数static
静态函数没有this pointer,只能去处理静态变量
调用静态函数的方法:通过对象调用(跟普通类一样);通过类(class name)调用。
即:
class Account {
public:
static double m_rate;
static voidset_rate(const double& x) {
m_rate = x;
}
};
使用:
Account::set_rate(5.0);
或者
Account a;
a. set_rate(7.0); // 这种方法不同于普通对象的地方在于,它也不传this poiner给参数。
Static的使用例子,单例模式
详见pdf文档。
另外,static变量(包括全局和局部的)只初始化一次,
如:
void print_static() {
static int a = 1;
a++;
cout << a << endl;
}
用for loop循环调用print_static十次,但a只会初始化赋值一次,所以a会从2递增到11.
Ø Cout
cout什么可以接受这么多种数据,并且可以打印出来?
初步考虑的话,可能是因为cout做了很多重载,可以接收int, string, char等不同类型的输出。具体看它的继承:
external _IOostream_withassign cout;
class _IOostream_withassign: publicostream { }
正因为上面做了很多重载,所以有输出不同类型数据的效果。
Ø 模板(类模板class template, 和 函数模板function template)
如果不想把类型写死,可以考虑使用模板。
template <typename T> //这一行就是告诉编译器,T还没有绑定,使用模板
定义了template,使用方法如
complex<double> c1(1, 1,); //要明确typename绑定什么类型
complex<int> c1(1, 1,);
上面两行,编译器没看到每一行,都会重新用类型替换一次类代码。
模板会造成代码的膨胀。但膨胀是必须的。
函数模板
template <class T> //class 和 typename同样效果
inline
const T& min(const T& a, constT& b) {
returnb<a?b:a;
}
编译器会对函数进行实参推导,然后将template的模板函数用实际函数替换一份代码。
例子中,min函数,只负责比大小,而怎么比则是数据类型的责任。
模板还有更多细节,如特化,偏特化。后面再详细学习。
Ø Namespace
Namespace std { //标准库namespace
}
可以在多个文件,将多个部分的类包括在std的space中。
如何使用namespace,下面有三种用法
using directive 使用命令
usingnamespace std; //全部打开std
using declaration
usingstd::cout; //只打开cout
不用using,如在函数中,直接使用std::cout << 2;
- C++面向对象高级编程笔记02--GeekBand
- C++面向对象高级编程笔记01--GeekBand
- C++面向对象高级编程笔记03--GeekBand
- 《GeekBand》c++面向对象高级编程02
- [GeekBand]C++面向对象高级编程(上)- 第一周笔记
- C++面向对象高级编程(上)-Geekband
- 《GeekBand》c++面向对象高级编程01
- 《GeekBand》c++面向对象高级编程03
- 《GeekBand》c++面向对象高级编程04
- Geekband C++面向对象高级编程(上) 第一周笔记 暗影行者
- Geekband C++面向对象高级编程(上) 第二周笔记 暗影行者
- Geekband C++面向对象高级编程(上) 第三周笔记 暗影行者
- Geekband C++面向对象高级编程(下) 第一周笔记 暗影行者
- Geekband C++面向对象高级编程(下) 第二周笔记 暗影行者
- GeekBand C++ 面向对象高级编程(上) 第一周笔记
- GeekBand C++ 面向对象高级编程(上) 第二周笔记
- GeekBand C++ 面向对象高级编程(下) 第三周笔记
- GeekBand C++ 面向对象高级编程(下) 第四周笔记
- java枚举使用详解
- iOS证书描述文件说明
- Remove Linked List Elements
- Android最佳实践 —— 详细谈谈如何减小APK体积
- Ubuntu下 嵌入式Qt开发环境的搭建--转载
- C++面向对象高级编程笔记02--GeekBand
- 使用Jmeter进行Web站点性能测试实例
- PAT-Be Unique (20)
- 数据结构之“Ordered List and Sorted List”(七)
- 8A大功率直流稳压电源设计
- 三角剖分算法(delaunay)
- DFS(深度优先遍历搜索解析)
- POJ-1321-棋盘问题
- fgets()和fputs()的使用