美文网首页C++程序员
C++类对象和类指针 剖析

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

作者: litexy | 来源:发表于2017-11-27 21:12 被阅读0次

有下面的一个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

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


感谢您的阅读!

相关文章

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

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

  • 1.2.09_C++ 指向类的指针

    C++ 类 & 对象 一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算...

  • 类中定义自身类的对象

    类中定义自身类的对象 在C++的类定义中,是不能够在类中定义自身类的对象的,但是可以定义自身类的指针对象和引用。 ...

  • 10 多态 抽象

    /*多态本质:c++ 允许将派生类对象的地址赋予基类的指针所有派生类的本质都是is a 的基类基类的指针调用任何方...

  • C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 辅助类 智能指针类 使用测试 参考: C++ 引用计数技术及智能指针...

  • 1.2.08_C++ this 指针

    C++ 类 & 对象 在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员...

  • 类对象、元类

    任何实例的isa指针指向其类对象,类对象的isa指针指向其元类对象,元类对象的isa指针指向根元类对象,根元类对象...

  • iOS开发中方法查找流程图

    实例对象的isa指针指向类对象,类对象的isa指针指向元类,元类的isa指针指向根元类,根元类的isa指针指向自己...

  • C++ 面向对象 一

    C++ 面向对象 c++创建对象的时候如果使用new运算符,将会返回返回一个指针,指向堆中的内存地址 类,对象类定...

  • C++ 指向类的指针

    原文地址:C++ 指向类的指针 一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成...

网友评论

    本文标题:C++类对象和类指针 剖析

    本文链接:https://www.haomeiwen.com/subject/dkcjbxtx.html