1. 类中含有指针—— class with pointer member(s) ——的情况经常发生,典型的有:string 类。

2. STL中的 string 类太复杂,copy on write 等等特性。

3. 采用“防卫式头文件声明”。

4. s2 赋值给 s3。

String s3("hello"), s2;
s3 = s2;

5. complier 会默认生成:拷贝构造函数 和 拷贝赋值函数(操作符重载),其执行的原理是按位依次赋值。带指针的类不适合使用默认的构造函数。

class String
{
public:
String (const String& str); //拷贝构造函数
String& operator= (const String& str); //拷贝赋值函数
} String s3(s1); //拷贝构造
String s2 = s3; //拷贝赋值

6. String 类实现原理

class String
{
public:
String(const char* cstr=);
private:
char* m_data; //指针动态分配存储空间
} String::String(const char* cstr)
{
if (cstr) {
m_data = new char[strlen(cstr)+];
strcpy(m_data, cstr);
}
else {
m_data = new char[];
*m_data = '\0';
}
}

7. 只要类中带有指针,就必须自定义拷贝构造函数和拷贝赋值函数。

8. 三个特殊函数(big three):拷贝构造、拷贝赋值、析构函数。

9. 尽量使用“常量成员函数”:

char* get_c_str() const
{
//do something
}

10. 浅拷贝:编译器默认生成的类实例间拷贝行为,对带有指针的类来说会引发 memory leak。

深拷贝:用户定义的行为(实质是一种构造函数)。

兄弟——类的不同实例——间互为 friend(友元),可以直接取对方的私有成员。

11. 一定要在 operator= 中检查是否 self assignment,是编程经验的体现。

String& String::operator=(const String& str)
{
// check self assignment
if (this == &str)
return *this; delete[] m_data;
m_data = new char[ strlen(str.m_data) + ];
strcpy(m_data, str.m_data);
return *this;
}

12. stack and heap

stack:

存在于某scope(作用域)的一块内存空间(memory space)。例如当用户调用函数,函数本身会形成一个stack用来放置它所接收的参数,以及返回地址。

在函数本体内声明的任何变量,其所使用的内存块都取自上述stack。

heap:

或谓 system heap,是指操作系统提供的一块 global 内存空间,程序可动态分配(dynamic allocated)从某中获得的若干区块。

13. stack object 对象的生命期:

class Complex {......};
......
{
Complex c1(, );
}

c1便是 stack object,其生命在作用域(scope)结束之际结束。这种作用域之内的 object 又称为 auto object,因为它会被“自动”清理。

14. static local object 对象的生命期:

class Complex {......};
......
{
static Complex c2(, );
}

c2便是static object,其生命期在作用域(scope)结束之后仍然存在,直到整个程序结束。

15. global object 对象的生命期:

class Complex {......};
......
Complex c1(, ); int main()
{
//do sometihing
return ;
}

c1便是所谓 global object,其生命期在整个程序结束之后才结束,也可以视为一种 static object,作用域是“整个程序”。

16. (对象的) 存在/消失 ≈ 构造/析构 (函数)何时被调用。

17. heap objects 对象的生命期:

class Complex {......};
...
{
Complex *p = new Complex;
...
delete p;
}

p 所指的是 heap objects ,其生命在它被 delete 之际结束。

若当作用域结束还未 delete 则会内存泄漏(memory leak):因为当作用域结束时,指针p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到指针p,也就没机会 delete p。

18. new: 先分配memory,再调用constructor

Complex *p = new Complex(1, 2);

以上的一行代码,编译器会转化为:

Complex *pc;

void* mem = operator new( sizeof( Complex ) ); // 分配内存
pc = static_cast<Complex*>(mem); // 转型
pc->Complex::Complex(, ); // 构造函数
  • operator new——操作符“new”——是C++函数,其内部调用malloc()。
  • pc->Complex::Complex(1, 2); => Complex::Complex(pc, 1, 2); / Complex::Complex(this, 1, 2);

19. delete:先调用 de-constructor,在释放内存

Complex *ps = new String("hello world");
...
delete ps;

编译器转化为

Complex::~Complex(ps); // 析构函数
operator delete(ps); // 释放内存
  • operator delete(ps); 内部调用 free(ps)

20. array new 一定要搭配 array delete。

String *p = new String[];
...
delete[] p;

21. 头文件.h 防卫式声明

22. 32位平台下,一根指针 4 字节。

23. return by reference 使用门槛:传递的 object 不是 local object。

24. “常量成员函数”:不修改类成员数据部分的函数。

char* get_c_str() const
{
// do something
}

const 加在 ()与{}之间。

25. inline 关键字一定要加!全部的,无负面作用。

26. static data member 内存中只有一份,不在乎存在多少实例。

static data memeber 一定在类的声明之外设初值。

static member function 调用方式有二:(1)通过 object 调用(2)通过 class name 调用。

class Account {
static void set_rate(double val);
}; Account::set_rate(8.0); // 通过类名调用 Account a1;
a1.set_rate(8.0); // 通过实例调用

27. Q:“声明”和“定义”的区别?

A:定义会程序获得内存。

28. singleton——把ctor放在private区

class A{
public :
static A& getInstance(){ return a; }
setup();
private:
A();
A(const A& ths);
static A a;
};
// 调用示例
A::getInstance().setup();

29. Meyer`s singleton——把ctor放在private区

把静态的“自己”放在函数里。好处:只有当函数被调用时,才创建object,即使离开函数以后static object也依然存在。如果该函数没被调用过,那么连一个static object也不会存在。

class A{
public :
static A& getInstance();
setup();
private:
A();
A(const A& ths);
static A a;
}; A& A::getInstance()
{
static A a;
return a;
}
// 调用示例
A::getInstance().setup();

30. Q:为什么cout可以接收各种内置类型“对象”?

A:因为标准库对“<<”做了针对各种内置类型的运算符重载

31. “template会造成代码膨胀是必要的”——侯捷

代码膨胀:模版会针对用户定义的每一种类型都生成一份代码,代码的大意相同,只是类型不同。

32. class template

template <typename T>
class Complex {
public:
Complex(T r = , T i = )
: re(r), im(i)
{}
private:
T re, im;
}; int main()
{
complex<double> c1(, );
return ;
}

33. function template

class Complex {
public:
bool operator< (const Complex& ths) const
{...}
}; template <class T>
inline const T& min(const T& a, const T& b)
{
return b < a ? b : a; // 编译器遇到“<”会自动寻找对应类型的运算符重载
} int main()
{
Complex c1, c2, c3;
c3 = min(c1, c2);
}

对于 c3 = min(c1, c2) 不必明确指出类型,因为complier会对function template进行实参推导(argument deduction)。

34. namespace

using directive

using namespace std;

using declaration

using std::cout

std::cin >> ...
cout << ...

35. string.h 代码:

#ifndef __MYSTRING__
#define __MYSTRING__ class String
{
public:
String(const char* cstr=);
String(const String& str);
String& operator=(const String& str);
~String();
char* get_c_str() const { return m_data; }
private:
char* m_data;
}; #include <cstring> inline
String::String(const char* cstr)
{
if (cstr) {
m_data = new char[strlen(cstr)+];
strcpy(m_data, cstr);
}
else {
m_data = new char[];
*m_data = '\0';
}
} inline
String::~String()
{
delete[] m_data;
} inline
String& String::operator=(const String& str)
{
if (this == &str)
return *this; delete[] m_data;
m_data = new char[ strlen(str.m_data) + ];
strcpy(m_data, str.m_data);
return *this;
} inline
String::String(const String& str)
{
m_data = new char[ strlen(str.m_data) + ];
strcpy(m_data, str.m_data);
} #include <iostream>
using namespace std; ostream& operator<<(ostream& os, const String& str)
{
os << str.get_c_str();
return os;
} #endif

36. 更多细节深入

•operator type() const;
•explicit complex(…) : initialization list { }
•pointer-like object
•function-like object
•Namespace
•template specialization
•Standard Library
•variadic template (since C++11)
•move ctor (since C++11)
•Rvalue reference (since C++11)
•auto (since C++11)
•lambda (since C++11)
•range-base for loop (since C++11)
•unordered containers (Since C++)

C++面向对象高级开发课程(第二周)的更多相关文章

  1. C++面向对象高级开发课程(第三周)

    一,类与类之间的关系:继承(Inheritance).复合(Composition).委托(Delegation). 二,复合:表示 is-a ,该设计思想可以参照C语言的 struct . 1. 例 ...

  2. C++面向对象高级开发课程(第一周)

    0. 内存分区 计算机中的内存在用于编程时,被人为的进行了分区(Segment),分为: -“栈区”(Stack) -“堆区”(Heap) -全局区(静态 区,Static) -文字常量区和程序代码区 ...

  3. python课程第二周重点记录

    python课程第二周重点记录 1.元组的元素不可被修改,元组的元素的元素可以被修改(字典在元组中,字典的值可以被修改) 2.个人感觉方便做加密解密 3.一些方法的使用 sb = "name ...

  4. j2ee高级开发技术课程第二周(web请求的整个过程、XML)

    博客非原创,只是收集整理了一下网上的一些文章 一.web请求的整个过程 1)把URL分割成几个部分:协议.网络地址.资源路径.其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括 ...

  5. 201871010115——马北《面向对象程序设计JAVA》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  6. 杨其菊201771010134《面向对象程序设计Java》第二周学习总结

    第三章 Java基本程序设计结构 第一部分:(理论知识部分) 本章主要学习:基本内容:数据类型:变量:运算符:类型转换,字符串,输入输出,控制流程,大数值以及数组. 1.基本概念: 1)标识符:由字母 ...

  7. 《Linux内核分析》课程第二周学习总结

    姓名:何伟钦 学号:20135223 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  8. 201777010217-金云馨《面向对象程序设计(Java)》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  9. 201871010132——张潇潇《面向对象程序设计JAVA》第二周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

随机推荐

  1. ZJU-1003 Crashing Balloon dfs,

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3 题意(难以描述):A,B两个人从1~100选数乘起来比谁的大(不能选重复的或者 ...

  2. SecTools.Org--bp

    Burp Suite使用介绍(一) | WooYun知识库  http://drops.wooyun.org/tips/2227     我的渗透利器 | EVILCOS             fr ...

  3. android udev

    http://www.freesoftwaremagazine.com/articles/drivers_linux http://blog.csdn.net/jianchi88/article/de ...

  4. In MySQL, a zero number equals any string

    最近在做项目的过程中发现了一个问题 数据库表 test  有个字段是 target_id  int(11),这个字段可能为零 使用如下查询 select * from test where targe ...

  5. Making the Grade---poj3666(dp)

    题目链接:http://poj.org/problem?id=3666 题意:有一个n个数的序列a,现在要把这些序列变成单调增的或者单调减的序列 b , 其价值为|A1 - B1| + |A2 - B ...

  6. 洛谷P3557 GRA-Tower Defense Game [POI2013] 构造

    正解:构造 解题报告: 传送门 话说这题我理解题意理解了好久TT一直没懂那个,k的意义是什么,,,后来才明白,可能k就是没有意义的趴 (upd:好像明白辣,k是用来保证这么做是对的QwQ 然后就直接港 ...

  7. 【Pyton】【小甲鱼】文件

    1.打开文件的集中模式: 2.文件对象方法: 对于文件对象方法的练习代码: 读取F:\\script\\script.txt位置文件中内容 >>> f=open('F:\\scrip ...

  8. 分布式网格缓存Coherence简介

    Coherence企业级缓存(一) 特点 摘要:Oracle Coherence是一个企业级的分布式集群缓存框架.具有自管理,自恢复,高可用性,高扩展性等优良特点,在电信BOSS等项目中有很大的应用价 ...

  9. sysbench的安装和做性能测试

    sysbench的安装和做性能测试 http://imysql.cn/node/312 sysbench是一个模块化的.跨平台.多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况. ...

  10. word自动导入目录

    1:如果在编写word时,有给各章添加标题,可以使用word的目录生成功能,如图: