继承机制中的构造器和析构器

  正如此前所讲解的,C++支持程序员自己写出将创建或销毁一个对象时自动调用的方法,也就是构造器和析构器。
  在没有继承机制的情况下,我们很容易理解这些方法在创建或销毁一个对象的时候被调用。但是一旦使用了继承机制,构造器和析构器就变得有点复杂了。
  比如基类有个构造器,如Animal(),它将在创造Pig 类型的对象时最先被调用,如果Pig类也有一个构造器,它将排在第二个被调用。因为基类必须在类之前初始化原则!

  然后我们继续讨论:如果构浩器带着输入参数,事情变得稍微复杂了。

class Animal{
public:
    Animal(std::string theName);
    std::string name;
}
class Pig:public Animal{
public:
    Pig(std:string theName);
}

  那么我们的方法应该如何定义呢?

Animal::Animal(std::string theName){
    name=theName;
}
Pig::Pig( std:string theName):Animal( theName){
}

  注意在子类的构造器定义里的":Animal(theName)"语法含义是:当调用Pig()构浩器时(以theName作为输入参数),Animal()构浩器也将被调用(theName 输入参数将传递给它)。于是,当我们调用Pig pig(“小猪猪");将把字符串“小猪猪“传递给Pig()和Animal(),赋值动作将实际发生在Animal()方法里。

  实践:test

#include <iostream>
#include <string>

class Animal
{
public:
    std::string mouth;
    std::string name;

    Animal(std::string theName);
    void eat();
    void sleep();
    void drool();
};

class Pig : public Animal
{
public:
    void climb();
    Pig(std::string theName);
};

class Turtle : public Animal
{
public:
    void swim();
    Turtle(std::string theName);
};

Animal::Animal(std::string theName)
{
    name = theName;
}

void Animal::eat()
{
    std::cout << "I'm eatting!" << std::endl;
}

void Animal::sleep()
{
    std::cout << "I'm sleeping!Don't disturb me!" << std::endl;
}

void Animal::drool()
{
    std::cout << "我是公的,看到母的我会流口水,我正在流口水。。。" << std::endl;
}

Pig::Pig(std::string theName) : Animal(theName)
{
}

void Pig::climb()
{
    std::cout << "我是一个只漂亮的小母猪猪,我会上树,我正在爬树,嘘。。。" << std::endl;
}

Turtle::Turtle(std::string theName) : Animal(theName)
{
}

void Turtle::swim()
{
    std::cout << "我是一只小甲鱼,当母猪想抓我的时候,我就游到海里。。哈哈。。" << std::endl;
}

int main()
{
    Pig pig("小猪猪");
    Turtle turtle("小甲鱼");

    std::cout << "这只猪的名字是: " << pig.name << std::endl;
    std::cout << "每只乌龟都有个伟大的名字: " << turtle.name << std::endl;

    pig.eat();
    turtle.eat();
    pig.climb();
    turtle.swim();

    return 0;
}
View Code

  在销毁某个对象时,基类的析构器也将被自动调用,但这些事情编译器会自动替你处理。因为析构器不需要输入参数,所以根本用不着使用:SuperClassMethod(arguments)语法!
  与构造器的情况相反,基类的析构器将在子类的最后一条语句执行完毕后才被调用。为了让大家对上面有绍的执行流程有比较直观的印象,我们来编写一个小程序:example

#include <iostream>
#include <string>

class BaseClass//基类 
{
public:
    BaseClass();//构造器 
    ~BaseClass();//析构器 

    void doSomething();//方法 
};

class SubClass : public BaseClass//定义子类且继承基类 
{
public:
    SubClass();//子类构造器 
    ~SubClass();//子类析构器 
};

BaseClass::BaseClass()//定义基类构造器 
{
    std::cout << "进入基类构造器。。。。。\n";
    std::cout << "我在基类构造器里边干了某些事。。。。\n\n";
}

BaseClass::~BaseClass()//定义基类析构器 
{
    std::cout << "进入基类析构器.......\n";
    std::cout << "我在基类析构器里边也干了某些事。。。。\n\n";
}

void BaseClass::doSomething()//定义基类的方法 
{
    std::cout << "我是基类的方法,我干了某些事。。。。\n\n";
}

SubClass::SubClass()//定义子类构造器 
{
    std::cout << "进入子类构造器.....\n";
    std::cout << "我在子类构造器里边还干了某些事.....\n\n";
}

SubClass::~SubClass()//定义子类析构器 
{
    std::cout << "进入子类析构器......\n";
}

int main()
{
    SubClass subclass;//定义了一个名为 subclass的对象 
    subclass.doSomething();

    std::cout << "完事,收工!\n";

    return 0;
}
进入基类构造器。。。。。
我在基类构造器里边干了某些事。。。。

进入子类构造器.....
我在子类构造器里边还干了某些事.....

我是基类的方法,我干了某些事。。。。

完事,收工!
进入子类析构器......
进入基类析构器.......
我在基类析构器里边也干了某些事。。。。

请按任意键继续. . .
View Code



猜你喜欢

转载自www.cnblogs.com/tianqizhi/p/10271180.html
今日推荐