第二十四课:经典问题解析二----------狄泰软件学院

一、构造函数与析构函数的调用顺序

(1)、单个对象创建时构造函数的调用顺序

1.调用父类的构造过程
2.调用成员变量的构造函数(调用顺序与声明顺序相同)
3.调用类自身的构造函数
4.析构函数与对应的构造函数调用相反(先类自身再类成员最后父类)

(2)、多个对象析构时

析构顺序与构造顺序相反

#include <iostream>
using namespace std;
class Member
{
    const char* ms;
public:
    Member(const char* s)
    {
        cout << "Member(const char* s):" << s << endl;

        ms = s;
    }
    ~Member()
    {
        cout << "~Member(): "<< ms << endl;
    }
};

class Test
{
    Member mA;
    Member mB;
public:
    Test() : mB("mB"), mA("mA")
    {
        cout << "Test()" << endl;
    }
    ~Test()
    {
        cout << "~Test()" << endl;;
    }
};

Member gA("gA");

int main()
{
    Test t;

    return 0;
}
打印结果:
Member(const char* s):gA
Member(const char* s):mA
Member(const char* s):mB
Test()
~Test()
~Member(): mB
~Member(): mA
~Member(): gA

结论:

1.对于栈对象和全局对象,类似于入栈和出栈顺序,最后构造的会最先被析构
2.对于堆对象,析构顺序与delete调用顺序有关

二、const关键字是否可以修饰类对象

1.const可以修饰对象,变成只读对象
2.只读对象的成员变量不允许改变
3.只读对象是编译阶段的概念,运行时无效

c++的const成员函数
1.const对象只能调用const的成员函数
2.const成员函数中只能调用const成员函数
3.const成员函数中不能直接改写成员变量的值
4.const成员函数的定义:函数声明之后函数体之前加上const关键字

#include<iostream>
using namespace std;
class Test
{
private:
    int mi;
public:
    int mj;
    Test(int i);
    Test(const Test& obj);
    int getMi() const;
};

Test::Test(int i)
{
    mi = i;
}

Test::Test(const Test& obj)
{
    mi = obj.getMi();//const Test& obj说明是只读的,如果getMi()不是只读的,这行就会出错
}

int Test::getMi() const
{
    //mi = 5;//只读对象的成员变量不允许改变
    return mi;
}

int main()
{

    const Test t(1);
//  t.mj = 5;//只读对象的成员变量不允许改变
    cout << t.getMi()<<endl;
    return 0;
}

三、成员函数和成员变量都是隶属于具体对象的么?

1.从面向对象的角度看:对象由属性(成员变量)和方法(成员函数)构成
2.从程序运行角度:对象由数据和函数构成
数据位于栈、堆和全局数据区
函数只能位于代码段(所以所有对象共有一套成员函数)

#include <iostream>
using namespace std;
class Test
{
    int mi;
public:
    int mj;
    Test(int i);
    Test(const Test& t);
    int getMi();
    void print();
};

Test::Test(int i)
{
    mi = i;
}

Test::Test(const Test& t)
{
    mi = t.mi;
}

int Test::getMi()
{
    return mi;
}

void Test::print()
{
   cout <<"this = " << this << endl;
}

int main()
{
    Test t1(1);
    Test t2(2);
    Test t3(3);

    cout << "t1.getMi() = " << t1.getMi() << endl;
    cout << "&t1 = " << &t1 << endl;
    t1.print();

    cout << "t2.getMi() = " << t2.getMi() << endl;
    cout << "&t2 = " << &t2 << endl;
    t2.print();


    cout << "t3.getMi() = " << t3.getMi() << endl;
    cout << "&t3 = " << &t3 << endl;
    t3.print();


    return 0;
}
打印结果:
t1.getMi() = 1
&t1 = 0xbfc94068
this = 0xbfc94068
t2.getMi() = 2
&t2 = 0xbfc94070
this = 0xbfc94070
t3.getMi() = 3
&t3 = 0xbfc94078
this = 0xbfc94078

结论:

1.每个对象都拥有自己独立的属性(成员变量)
2.所有对象共享类的方法(成员函数)
3.方法能够直接访问类的属性(成员函数只有一套,成员函数能够访问对应类的所有对象的成员变量)
4.那程序怎么知道是哪个对象调用了成员函数呢(方法中的隐藏参数this用于指代当前对象)

小结:

1.对象的析构顺序与构造顺序相反
2.const关键字能够修饰对象,得到只读对象
3.只读对象只能调用const成员函数
4.所有对象共享类的成员函数
5.隐藏的this指针用于表示当前对象从而分辨哪个对象调用了成员函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值