C++类对象和类指针 剖析

有下面的一个CPerson类:

class CPerson
{
public:
    void show()
    {
        cout<<"I am a people"<<endl;
    }
};

在实际编程中,我们经常会看到一个类型有下面两种不同的使用方式:

CPerson s1;
CPerson *s2 = NULL;
s2 = new CPerson();
s1.show();
s2->show();
delete s2;

那么这两者在实际的使用中到底有何差别呢,下面从不同的方面来剖析一下。

调用方式上的不同

首先二者最明显的区别就是调用方式上的不同,对象使用" . "操作符调用,而指针使用" -> "操作符调用,且指针在调用时需要先用new来分配空间,且用完后必须手动delete掉。如不想手动delete也可使用智能指针。

内存空间上的不同

二者的类型决定了它们在内存上的分布不同,一个是对象类型,一个是指针类型。对象类型在创建时就已为对象分配好内存空间,用的是内存栈,是个局部的临时变量,作用域在该函数体内,随函数的结束被释放。

指针变量在创建时也是在内存栈,里面的值是对象的地址,当用new操作符时会在内存堆上分配一个空间,即存储实际的对象内容,此时的指针变量里的值即为刚刚分配的内存地址。所以为什么要用delete释放呢?这是因为内存栈里的变量会随着函数的结束而释放,内存堆里的内容需要用户手动释放,所以当函数调用结束时,指针变量会被释放,如果不先delete的话,内存堆里的内容就会找不到地址,也就"无人看管"了。所以在实际使用中一定要记得用完后delete,若是数组,则是delete[]。

作为函数参数的不同

类的对象和指针都可作为函数参数传递,这其中还可以有一个引用,代码如下:

void func(CPerson object)
void func(CPerson* object)
void func(CPerson &object)

那么这几种方式有何区别呢?下面来一一分析一下。
1: void func(CPerson object)
这种函数是非常不建议的,因为函数参数压栈时,对object进行了复制(还记得拷贝构造函数吗),所以函数对object的操作实际上是对新的对象空间进行的操作,不会影响原对象空间。由于不必要的拷贝对象是十分浪费时间的,也没有意义,我们完全可以用函数func(const Cobject& object);来代替,同样能保护对象的只读性质。
2:void func(CPerson object)
这种方式是将类指针作为参数,函数压入参数时实际上复制了指针的值(其实指针可以看作一个存放地址值的整形),实际复制的指针仍指向原对象的空间,所以func函数对该指针的操作是对原对象空间的操作。
3: void func(CPerson &object)
这种方式和传指针类似,但函数压入参数时实际上复制了object对象的this指针,其实this指针不是一个真正存在的指针,可以看作是每个对象的数据空间起始地址。func函数中对this指针的操作,实际上也是对原对象空间的操作。

不管值传递,引用传递啊乱七八遭的什么东西,反正调用函数时都是会复制参数的,只是不同的是复制的是地址,还是整个对象空间的区别而已。
相同的,函数CPerson func(CPerson& object);在return CPerson对象时,同样会进行构贝构造。这些隐藏的对象复制都是不需要的,我们可以改为CPerson& func(CPerson& object);或是CPerson* func(CPerson& object);这样,在return时,就只是对指针(地址)的复制而已。在不是特殊的情况下,不要将整个对象作为参数,也不要返回整个对象。

类指针实现多态

还有一个显著区别就是类指针可以实现多态,通过分类指针调用子类对象,下面详细说明。
C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。

1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。
2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
4:多态用虚函数来实现,结合动态绑定.
5:纯虚函数是虚函数再加上 = 0;
6:抽象类是指包括至少一个纯虚函数的类。纯虚函数:virtual void fun()=0;即抽象类!必须在子类实现这个函数,即先有名称,没有内容,在派生类实现内容。

下面看一个具体例子:

class CPerson
{
public:
    virtual void show()
    {
        cout<<"I am a people"<<endl;
    }
};

class CStudent:public CPerson
{
public:
    void show()
    {
        cout<<"I am a student"<<endl;
    }
};

int main()
{
    CStudent stu;
    CPerson *per = &stu;
    per->show();
    system("pause");
    return 0;
}

输出的结果为:


运行jie

可以看到父类指针指向子类对象后,调用的是子类的show函数,注意多态的实现需要在函数前加virtual修饰,使其为虚函数,否则调用的还是父类的,总之要实现多态,类指针和虚函数缺一不可。关于多态的详细分析具体可以参考http://www.cnblogs.com/cxq0017/p/6074247.html

通过以上对类对象和类指针不同方面的分析,我们在知道在什么时候应该使用类对象,什么时候使用类指针比较好。


感谢您的阅读!

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

推荐阅读更多精彩内容