C++面向对象高级编程(上)-第二周-博览网

第二周

三大函数:拷贝构造,拷贝赋值,析构

字符串的构造函数,拷贝构造函数,

int main()
{
    String s1();
    String s2("hello");

    String s3(s1);      ///调用拷贝构造函数
    cout << s3 << endl;

    s3 = s2;            ///s2赋值给s3,拷贝赋值函数

    cout << s3 << endl;
}

拷贝构造函数和拷贝赋值函数没有自主定义时,编译器会给出默认,默认按位拷贝,成员带有指针时,只拷贝指针内容,两个指针指向同一地方。

类内带指针时,要自己定义拷贝构造和拷贝赋值函数

class String
{
public:
    String(const char * cstr = 0);
    String(const String & str);     ///参数为本类
    String& operator=(const String & cstr);     ///参数为本类
    ~String();
    char* get_c_str() const {return m_data;}
private:
    char* m_data;       ///动态分配
};
inline
String::String(const char* cstr = 0)
{
    if (csrt)
    {
        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;    ///不delete 内存泄漏
}

字符串的表示方式:

  • 不知道长度,但是最后有\0;

  • 没有结束符号,但是有长度声明

delete 与delete[]

class with pointer members 必须有copy ctor 和copy op=

默认拷贝是不会拷贝动态分配的内存的

String a("Hello");
String b("Wworld");
b = a;      ///浅拷贝,别名

copy ctor(拷贝构造函数)

inline
String::String(const String & str)
{
    m_data = new char[strlen(str.m_data) + 1];
    strcpy(m_data,str.m_data);  //直接取另一个object的private成员
}
{
    String s1("Hello");
    String s2(s1);
    //String s2 = s1;
}

拷贝赋值函数

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

一定要在operator= 函数中检查是否self assignment

stack(栈)和heap(堆)

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

在函数本体(function body)内声明的任何变量,其所使用的内存块都取自stack

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

class Complex{....};

{
    Complex cl(1,2);        //空间来自stack
    Complex* p = new Complex(3);  //Complex(3)是个临时对象,其所占用的
                             ///空间是new自heap的动态分配而得,并由p指向
}

stack object的声明周期

c1就是stack object,其声明在作用域(scope)结束之际结束,这种作用域内的object,又称为auto object,因为它会被“自动”清理(自动调用析构)

static local objects的声明周期

class Complex{...};

{
    static Complex c2(1,2);
}

c2 就是static object ,其生命在作用域结束之后仍然存在,直到整个程序结束(静态对象)

global object

class Complex{...};

Complex c3(1,2)

{
    .....
}

c3便是global object ,其生命在整个程序之后结束,作用域是整个程序

heap objects 的生命周期

class Complex{...};


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

p所指的便是heap object,其生命在它被deleted之际结束

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

以上出现内存泄漏(memory leak),因为当作用域结束,p所指向的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到p(也就没有了栈会delete p)

new:先分配memory,再调用ctor

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

编译器转化为:

Complex *pc;
    void* mem = operator new(sizeof(Complex));  //分配内存,内部调用malloc(n)
    pc = static_cast<Complex*>(mem);            //转型
    pc->Complex::Copmlex(1,2);                  //构造函数

delete :先调用dior,在释放memory

Complex* pc = new Complex(1,2);
...
delete pc;

编译器转化为:

Complex::~Complex(pc);  //析构函数
operator delete(pc);    //释放内存,内部调用free
String* pc = new String("Hello");
...
delete ps;

被编译器转化为:

String::~String(ps);    ///析构函数,删除自分配的内存
operator delete(ps);    ///释放内存,杀掉字符串

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

VS分配内存块

new一个Complex时,在调试模式下,会得左一的结果(每条代表4个字节),

  • 灰色:系统内存
  • 砖红色:cookie,记录整块内存大小,便于回收
  • 浅绿色:对象的内存
  • 深绿色:pad,补充内存(必须是16的倍数)

64的十六进制标识是40,此处cookie是41,最后一位表示这块内存是给出去还是收回来

release模式下分配内存为左2

动态分配得到的数组

VS动态分配数组

Complex * p = new Complex[3];//debug时对应左一

  • 白色:用一个整数记录长度
  • 浅灰色:三个Comlex

String* p=new String[3]; ///对应右二

new与delete成对使用

new[]与delete[]成对使用

内存泄漏时,cookie之间的内存不会泄漏,但是当写为delete[]时,编译器才会调用多次析构函数,释放各自对象分配的内存,否则只会调用一次析构函数

类模板、函数模板、及其他

static

静态数据与静态函数

只有一份在内存里,静态函数没有this指针,只能处理静态数据

class Account
{
public:
    static double m_rate;   //声明
    static void set_rate(const double& x){m_rate = x;}
}
double Account::m_rate = 8.0;   //定义,初始化

int main()
{
    Account::set_rate(5.0);  //通过object调用
    Account a;          //通过class name调用
    a.set_rate(7.0);
}

调用static函数的方法

  • 通过object调用

  • 通过class name调用

把ctor放在private区 Singleton

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();

函数模板

stone r1(2,3),r2(3,3),r3;
r3 = min(r1,r2);        ///T为stone,则调用stone::operator<

template <class T>
inline
const T& min(const T& a,const T& b)
{
    return b < a ? b : a;
}

class stone
{
public:
    stone(int w,int h,int we):_w(), _h(h), _we(we){}
    bool operator< (const stone& rhs) const{return _we < rhs._we;}
private:
    int _w, _h, _we;
}

namespace

//using directive
using namespace std;

//using declaraion
using std::cout;
std::cin << ...;
cout << ...;

//
std::cim <<;
std::cout <<;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容