C专家编程 第11章 你懂得C,所以C++不再话下 11.7 如何调用成员函数

    如何调用成员函数
    调用类的成员函数的有趣方法。你必须在需要调用的成员函数前面附上类的实例名(或称类的变量,也就是对象)。
    Fruit melon, orange, banana;
    int main() {
        melon.slice();
        orange.juice();
        return 0;
    }

    只有这样做,这些成员函数才能被调用,并执行各自的任务。这有点像预定义的操作符。调用一个类对象的成员函数相当于面向对象编程语言所使用的“向对象发送一条信息”这个术语。

    每个成员函数都有一个this指针参数,它是隐式赋给函数的,它允许对象在成员函数内部引用对象本身。注意,在成员函数内部,你应该发现this指针并未显式出现,这也是语言本身所设计的。
    class Fruit {
        public: void peel(); 
        private: int weight, colories_per_oz;
    }; 
    void Fruit::peel() {
        printf("this ptr = %p", this);
        this->weight--;
        weight--;
    }
    Fruit apple;
    printf("address of apple = %x", &apple);
    apple.peel();

    /*
    **编程挑战 
    */
    /*
    *调用成员函数
    *1.调用在前面的例子中所编写的slice()和juice()成员函数。
    *2.试验一下this指针是否是隐式传递给每个成员函数的第一个参数。 
    */
    #include <stdio.h>
    #include <stdlib.h>
 
    class Fruit {
        public: void peel(); 
        private: int weight, colories_per_oz;
    }; 
    void Fruit::peel() {
        printf("this ptr = %p\n", this);
        this->weight--;
        weight--;
    }

    int main( void ){
        Fruit apple;
        printf("address of apple = %p\n", &apple);
        apple.peel();
    
        return EXIT_SUCCESS;
    }

输出:

    构造函数和析构函数
    绝大多数类至少具有一个构造函数。当创建类的一个对象时,会隐式地调用构造函数,它负责对象的初始化。与之相对应,类也存在一个清理函数,称为析构函数。当对象被销毁(超出生存期范围或进行delete操作,回收它所使用的堆内存)时,会自动调用析构函数。析构函数不如构造函数常用,它里面的代码一般用于处理一些特殊的终止要求以及垃圾收集等。有些人把析构函数当做一种保险方法来确保对象离开适当的范围时,同步锁总能够被释放。所以它们不仅清除对象,还清理对象所持有的锁。构造函数和析构函数是非常需要的,因为类外的任何函数都不能访问类的private数据成员。因此,你需要类内部有一个特权函数来创建一个对象并对其进行初始化。

    相对于C语言,这是一个小小的飞跃。在C语言中,只能使用赋值符号在变量定义时对它进行初始化,或干脆使它保持未初始化状态。可以在C++的类中声明多个构造函数,并通过参数来区分它们。构造函数的名字总是和类的名字一样:
    Classname::Classname(arguments) {
        ...
    } 
    以Fruit类为例:
    class Fruit {
        public: peel(); slice();juice();
        Fruit(int i, int j); //构造函数
        ~Fruit(); //析构函数
        private: int weight, calories_per_oz; 
    }; 
    //构造函数体
    Fruit::Fruit(int i, int j) {
        weight = i; calories_per_oz = j;
    } 
    //对象声明时由构造函数进行初始化
    Fruit melon(4, 5), banana(12, 8);
    构造函数是必要的,因为类通常包含一些结构,而结构又可能包含许多字段。这就需要复杂的初始化。当创建类的一个对象时,会自动调用构造函数,程序员永远不应该显式地调用构造函数。至于全局和静态对象,会在程序开始时自动调用它们的构造函数,而当程序终止时,会自动调用它们的析构函数。
    构造函数和析构函数违反了C语言中“一切工作自己负责”的原则。它们可以使大量的工作在程序运行时被隐式地完成,减轻了程序员的负担。这也违背了C语言的哲学,即语言中的任何部分都不应该通过隐藏的运行时程序来实现。 

    /*
    **编程挑战 
    */
    /*做一些清理工作
    *为Fruit类的析构函数编写函数体,里面包含一条printf()语句,并在一个内层的域中声明一个Fruit类的对象。需要在函数的头部添加#include<stdio.h>语句。然后,重新编译和运行a.out文件,看看当对象离开了它的生命域时是否调用了析构函数。 */
    #include <stdio.h>
    #include <stdlib.h>
    class Fruit {
        public: void peel(void); void slice(void); void juice(void);
        Fruit(int i, int j); //构造函数
        ~Fruit(void); //析构函数
        private: int weight, calories_per_oz; 
    }; 
    //构造函数体
    Fruit::Fruit(int i, int j) {
        weight = i; calories_per_oz = j;
    }
    //析构函数体
    Fruit::~Fruit( void ){
        printf( "destructor function is called.\n" );
    } 
    int main( void ){
        {
            //对象声明时由构造函数进行初始化
            Fruit melon(4, 5), banana(12, 8);
        }
    
        return EXIT_SUCCESS;
    }
输出:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_40186813

你的能量无可限量。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值