美文网首页
Boolan C++面向对象高级程序设计-第五周作业

Boolan C++面向对象高级程序设计-第五周作业

作者: lxidea | 来源:发表于2018-04-23 09:48 被阅读0次

    本周作业:

    为上周题目中的FruitApple添加构造函数与析构函数, 并在构造函数与析构函数中打印控制台信息,观察构造和析枸调用过程。然后为Apple类重载::operator new::operator delete,在控制台打印信息,并观察调用结果。

    于是首先添加构造函数和析构函数,然后观察构造和析构调用过程。
    这部分的Fruit和Apple类我都放在一个叫做fruit.h的头文件里。

    //
    // Created by laixi on 2018/4/22.
    //
    
    #ifndef WEEK5HM_FRUIT_H
    #define WEEK5HM_FRUIT_H
    
    #include <iostream>
    
    class Fruit{
    public:
        int no;
        double weight;
        char key;
    public:
        void print() {}
        virtual void process(){}
        Fruit() {
            std::cout << "Fruit::Fruit() ctor\n";
        }
        virtual ~Fruit() {
            std::cout << "Fruit::~Fruit() dtor\n";
        }
    };
    
    class Apple: public Fruit{
    public:
        int size;
        char type;
    public:
        void save() {}
        virtual void process(){}
        Apple():Fruit() {
            std::cout << "Apple::Apple() ctor\n";
        }
        ~Apple() {
            std::cout << "Apple::~Apple() dtor\n";
        }
    };
    
    #endif //WEEK5HM_FRUIT_H
    

    其中fruit作为父类,他的析构函数是虚函数的。
    那么在main函数中测试的代码就分别生成Apple和Fruit的实例就可以看出来了。
    主程序代码是:

    #include <iostream>
    #include "fruit.h"
    
    int main() {
        std::cout << "sizeof(Fruit)=" << sizeof(Fruit) << std::endl;
        std::cout << "sizeof(Apple)=" << sizeof(Apple) << std::endl;
        std::cout << "instantiation f, an object of Fruit\n";
        Fruit *f = new Fruit();
        std::cout << "instantiation a, an object of Apple\n";
        Apple *a = new Apple();
        std::cout << "deconstruction of Apple\n";
        delete a;
        std::cout << "deconstruction of Fruit\n";
        delete f;
        return 0;
    }
    

    运行的结果是:

    sizeof(Fruit)=32
    sizeof(Apple)=40
    instantiation f, an object of Fruit
    Fruit::Fruit() ctor
    instantiation a, an object of Apple
    Fruit::Fruit() ctor
    Apple::Apple() ctor
    deconstruction of Apple
    Apple::~Apple() dtor
    Fruit::~Fruit() dtor
    deconstruction of Fruit
    Fruit::~Fruit() dtor
    

    很显然,子类在构造的时候会预先构造它的父类,然后再调用自身的构造函数。

    按照题意,接下来将operator new()和operator delete()也进行重载

    //
    // Created by laixi on 2018/4/22.
    //
    
    #ifndef WEEK5HM_FRUIT_H
    #define WEEK5HM_FRUIT_H
    
    #include <iostream>
    
    class Fruit{
    public:
        int no;
        double weight;
        char key;
    public:
        void print() {}
        virtual void process(){}
        Fruit() {
            std::cout << "Fruit::Fruit() ctor\n";
        }
        virtual ~Fruit() {
            std::cout << "Fruit::~Fruit() dtor\n";
        }
        static void* operator new(size_t size) {
            Fruit* p = (Fruit*) malloc(size);
            std::cout << "Fruit::operator new(), size=" << size << ", return:" << p << std::endl;
            return p;
        }
        static void operator delete(void* pdead, size_t size) {
            std::cout << "Fruit::operator delete(), size=" << size << ", pdead=" << pdead << std::endl;
            free(pdead);
        }
    };
    
    class Apple: public Fruit{
    public:
        int size;
        char type;
    public:
        void save() {}
        virtual void process(){}
        Apple():Fruit() {
            std::cout << "Apple::Apple() ctor\n";
        }
        ~Apple() {
            std::cout << "Apple::~Apple() dtor\n";
        }
        static void* operator new(size_t size) {
            Apple* p = (Apple*) malloc(size);
            std::cout << "Apple::operator new(), size=" << size << ", return:" << p << std::endl;
            return p;
        }
        static void operator delete(void* pdead, size_t size) {
            std::cout << "Apple::operator delete(), size=" << size << ", pdead=" << pdead << std::endl;
            free(pdead);
        }
    };
    };
    
    
    #endif //WEEK5HM_FRUIT_H
    

    主程序改为

    #include <iostream>
    #include "fruit.h"
    
    int main() {
        std::cout << "sizeof(Fruit)=" << sizeof(Fruit) << std::endl;
        std::cout << "sizeof(Apple)=" << sizeof(Apple) << std::endl;
        std::cout << "instantiation f, an object of Fruit\n";
        Fruit *f = new Fruit();
        std::cout << "Fruit           = " << f << std::endl;
        std::cout << "Fruit.no        = " << &f->no << std::endl;
        std::cout << "Fruit.weight    = " << &f->weight << std::endl;
        printf("Fruit.key       = 0x%x\n",&(f->key));
        std::cout << "instantiation a, an object of Apple\n";
        Apple *a = new Apple();
        std::cout << "Apple           = " << a << std::endl;
        std::cout << "Apple.no        = " << &a->no << std::endl;
        std::cout << "Apple.weight    = " << &a->weight << std::endl;
        printf("Apple.key       = 0x%x\n",&(a->key));
        std::cout << "Apple.size      = " << &a->size << std::endl;
        printf("Apple.type      = 0x%x\n",&(a->type));
        std::cout << "deconstruction of Apple\n";
        delete a;
        std::cout << "deconstruction of Fruit\n";
        delete f;
        return 0;
    }
    

    输出将变为

    sizeof(Fruit)=32
    sizeof(Apple)=40
    instantiation f, an object of Fruit
    Fruit::operator new(), size=32, return:0x2727a20
    Fruit::Fruit() ctor
    Fruit           = 0x2727a20
    Fruit.no        = 0x2727a28
    Fruit.weight    = 0x2727a30
    Fruit.key       = 0x2727a38
    instantiation a, an object of Apple
    Apple::operator new(), size=40, return:0x2727d90
    Fruit::Fruit() ctor
    Apple::Apple() ctor
    Apple           = 0x2727d90
    Apple.no        = 0x2727d98
    Apple.weight    = 0x2727da0
    Apple.key       = 0x2727da8
    Apple.size      = 0x2727dac
    Apple.type      = 0x2727db0
    deconstruction of Apple
    Apple::~Apple() dtor
    Fruit::~Fruit() dtor
    Apple::operator delete(), size=40, pdead=0x30f7d90
    deconstruction of Fruit
    Fruit::~Fruit() dtor
    Fruit::operator delete(), size=32, pdead=0x30f7a20
    

    可以看到,重载之后,成员new的操作和delete的操作就替换为我们提供的版本了。

    在这个子类和父类重载函数的编写过程中,出现过一个奇特的点。我忘记写Apple的Operator delete()了。这个时候的运行过程,会发现Apple的析构会调用父类的析构函数。
    程序执行结果的最后四行就变成了

    Fruit::operator delete(), size=40, pdead=0x30f7d90
    deconstruction of Fruit
    Fruit::~Fruit() dtor
    Fruit::operator delete(), size=32, pdead=0x30f7a20
    

    相关文章

      网友评论

          本文标题:Boolan C++面向对象高级程序设计-第五周作业

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