第二周 C++面向对象高级编程(上)Boolan

Classes的两个经典分类:

  • Class without pointer member(s)
    complex
  • Class with pointer member(s)
    string

String class

第二周 C++面向对象高级编程(上)Boolan_第1张图片
String class

String s3(s1); // s3初值为s1,拷贝
s3=s2; //拷贝,引发与刚才不一样的函数

编译器给的默认的可以用,就用
但是这里不可以用,用的话会传指针,不是真的复制。

Big Three,三个特殊函数

第二周 C++面向对象高级编程(上)Boolan_第2张图片
Big Three,三个特殊函数

动态分配,而不是在类里面放一个数组。
所以是一个指针。

不能用编译器的,所以要写出来。
234是比 Complex 新增加的,Complex 里不曾出现
2.String 接受的是自己这种东西,所以叫拷贝构造
3.复制的是自己这种东西,拷贝赋值

所有的类的定义,对 big3都不会加 const,因为必然要修改

ctor 和 dtor(构造函数和析构函数)

第二周 C++面向对象高级编程(上)Boolan_第3张图片
ctor 和 dtor(构造函数和析构函数)

2-1
要想到最后有一个结束符'\0'
最后一步,清理的函数。
动态内存,所以要清理。否则会造成溢出。
class 里有指针,多半要使用动态分配,有动态分配,就要在退出时释放这部分内存。

class with pointer members 必须有 copy ctor 和 copy op=(赋值assignment operator)

第二周 C++面向对象高级编程(上)Boolan_第4张图片
class with pointer members 必须有 copy ctor 和 copy op=(赋值assignment operator)

如果使用编译器默认,则在赋值时会拷贝指针,而不是数据。
看起来像是内容相同,但是 a 和 b 指向了相同的数据,改变 a 同时也会改变 b。

copy ctor(拷贝构造函数)

第二周 C++面向对象高级编程(上)Boolan_第5张图片
copy ctor(拷贝构造函数)

2-2
alias 叠名
是一件危险的事

copy assignment operator(拷贝赋值函数)

第二周 C++面向对象高级编程(上)Boolan_第6张图片
copy assignment operator(拷贝赋值函数)

2-3
赋值过程:
先把左边清空,然后建立一个和右边一样的空间,再把右边拷贝到左边。
首先,检测是不是自我赋值,不只是同名赋值,很可能是指针指向同一个类。如果相同,就直接返回指针。
然后再拷贝:

  1. 删掉
  2. 建立空间
  3. 拷贝内容


    第二周 C++面向对象高级编程(上)Boolan_第7张图片
    赋值前
第二周 C++面向对象高级编程(上)Boolan_第8张图片
删掉
第二周 C++面向对象高级编程(上)Boolan_第9张图片
建立空间
第二周 C++面向对象高级编程(上)Boolan_第10张图片
拷贝内容

如果不检测自我赋值,会发生什么:

  1. 删掉了唯一值
  2. 无法建立空间,因为检测不出长度,出错
第二周 C++面向对象高级编程(上)Boolan_第11张图片
如果不检测自我赋值

output 函数

第二周 C++面向对象高级编程(上)Boolan_第12张图片
output 函数

要写操作符重载
有什么可以直接丢给 cout呢?有,写在 inline 里面的 get_c_str()

所谓 stack(栈),所谓 heap(堆)

第二周 C++面向对象高级编程(上)Boolan_第13张图片
所谓 stack(栈),所谓 heap(堆)

放在栈里的内容,在离开作用域后会自动删除
放在堆里的内容,需要自己手动删除

stack objects 的生命期

第二周 C++面向对象高级编程(上)Boolan_第14张图片
stack objects 的生命期

auto object

static local objects 的生命周期

第二周 C++面向对象高级编程(上)Boolan_第15张图片
static local objects 的生命周期

其生命在作用域结束之后仍然存在,直到整个程序结束。

globe object 的生命周期

第二周 C++面向对象高级编程(上)Boolan_第16张图片
globe object 的生命周期

heap objects 的生命周期

第二周 C++面向对象高级编程(上)Boolan_第17张图片
heap objects 的生命周期

new:先分配 memory,再调用 ctor

第二周 C++面向对象高级编程(上)Boolan_第18张图片
new:先分配 memory,再调用 ctor

绝大多数的 new 被分解为三个部分:

  1. 调用 operator new,其内部调用 malloc(n),分配内存的函数
  2. 转换类型
  3. 调用构造函数,全名是 Complex::Complex(this,i,j)
第二周 C++面向对象高级编程(上)Boolan_第19张图片
new:先分配 memory,再调用 ctor

delete:先调用 dtor,再释放 memory

第二周 C++面向对象高级编程(上)Boolan_第20张图片
delete:先调用 dtor,再释放 memory
  1. 执行析构函数~String(ps),删除字符串占用的空间
  2. 释放内存 operator delete(ps),调用free(ps)
第二周 C++面向对象高级编程(上)Boolan_第21张图片
delete:先调用 dtor,再释放 memory

动态分配所得的内存块(memory block),in VC

第二周 C++面向对象高级编程(上)Boolan_第22张图片
动态分配所得的内存块(memory block),in VC

VC调试中Complex占用的,复数占用8B,调试占用32+4,cookie,42,共52B,总共占用64B(必须是16的倍数)所以有34B 的填充物
Release Mode,8B,cookie 占用42,共16B
cookie 内容00000041,4代表4
16,1代表已分配
VC调试中String 占用的,指针占用4B,调试占用32+4,cookie,42,共48B,没有填充物
Release Mode,4B,cookie 占用4
2,共12B,总共占用16B,其中4B为填充物。

动态分配所得的 array

第二周 C++面向对象高级编程(上)Boolan_第23张图片
动态分配所得的 array

2-1
Complex* p=new Complex[3];

array new 一定要搭配 array delete

第二周 C++面向对象高级编程(上)Boolan_第24张图片
array new 一定要搭配 array delete

不正确的用法少了[],少了[]并不会发生array占用的内存泄漏。
有[]调用3次析构函数
没有[]调用1次析构函数,有两个并不回收

编程实例

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;
};

inline
String::String(const char* cstr=0)
{
    if (cstr){
        m_data = new char[strlen(cstr)+1];
        strcpy(m_data,cstr);
    }
    else{ //未指定初值
        m_data = new char[1];
        *m_data= '\0';
    }
}

inline
String::~String()
{
    delete[] m_data;
}

inline
String::String(const String& str)
{
    m_data = new char[ strlen(str.m_data) + 1];
    strcpy(m_data,str.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)+1];
    strcpy(m_data,str.m_data);
    return *this;
}

进一步补充:static

第二周 C++面向对象高级编程(上)Boolan_第25张图片
进一步补充:static

静态成员函数没有 this pointer,所以不能使用 this pointer 的功能。

第二周 C++面向对象高级编程(上)Boolan_第26张图片
进一步补充:static

静态的变量要在外面赋初值

进一步补充:把 ctors 放在 private 区

第二周 C++面向对象高级编程(上)Boolan_第27张图片
进一步补充:把 ctors 放在 private 区

只用一次的函数。构造函数放在 private 中,

第二周 C++面向对象高级编程(上)Boolan_第28张图片
进一步补充:把 ctors 放在 private 区

只有第一次调用的时候才会定义,这以后就会存在,并且只会有一份。

进一步补充:cout

第二周 C++面向对象高级编程(上)Boolan_第29张图片
进一步补充:cout

进一步补充:class template,类模板

第二周 C++面向对象高级编程(上)Boolan_第30张图片
进一步补充:class template,类模板

进一步补充:function template,函数模板

第二周 C++面向对象高级编程(上)Boolan_第31张图片
进一步补充:function template,函数模板

把责任分开,很有必要
这种东西叫做算法

进一步补充:namespace

第二周 C++面向对象高级编程(上)Boolan_第32张图片
进一步补充:namespace
  • using directive
using namespace std;
  • using declaration
using std:cont;
  • 用全名

更多细节与深入

第二周 C++面向对象高级编程(上)Boolan_第33张图片
更多细节与深入
  • operator tyge() const;
  • explicit complex(…):initialization list{}
  • pointer-like object
  • function-like object
  • Namespace
  • template specialization
  • Standard Library
  • variadic template
  • move ctor

你可能感兴趣的:(第二周 C++面向对象高级编程(上)Boolan)