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

  正如此前所讲解的,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;
}

  在销毁某个对象时,基类的析构器也将被自动调用,但这些事情编译器会自动替你处理。因为析构器不需要输入参数,所以根本用不着使用: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;
}

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

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

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

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

请按任意键继续. . .

原文地址:https://www.cnblogs.com/tianqizhi/p/10271180.html

时间: 2024-08-27 05:10:39

继承机制中的构造器和析构器的相关文章

理解继承中的构造器和析构器

1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class FatherClass 7 { 8 public: 9 FatherClass(); 10 ~FatherClass(); 11 }; 12 13 FatherClass::FatherClass() 14 { 15 cout << "this is FatherClass constructor"

c++第五章-(类与对象、构造器和析构器)

1.构造器与结构体的区别:构造器多支持方法.其作用有申请内存,初始化变量. 在c++中构造器没有返回值:语法Class Name(); 2.析构器的作用:释放内存. 在c++中析构器没有返回值:语法~ClassName(); class Animal { public: std::string mouth; std::string name; void eat(); void sleep(); void drool(); Animal(std::string theName); }; class

Python构造器及析构器:__init__与__new__及__del__

__init__与__new__这两个魔法方法组成了Python类对象的构造器,在Python类实例化时,其实最先调用的不是__init__而是__new__.__new__是负责实例化对象的,而__init__是初始化操作.__del__是析构器,当Python对象的所有引用都不存在了(被del了),就会自动触发__del__执行. class CapStr(str): def __new__(cls, string): #此时string = 'i love you' cls是CapStr这

构造器和析构器

一 构造器 swift的init方法是没有返回值的,而OC的init方法就有返回值,返回类本身 1.默认构造器 即使我们不写init方法,系统也会为函数默认写一个空的init方法 struct Fahrenheit {          var temperature:Double          init(){         temperature = 32.0     } } var f = Fahrenheit() 2.自定义构造器 struct Celsius {          

构造器与析构器

回顾:之前我们讨论了使用面向对象的编程技术开发程序最基本步骤: 定义一个有属性和方法的类(模板) 为该类创建一个变量(实现) 这是OOP技术的基础,现在逐步向大家介绍一些更复杂和更有用的概念. 首先是构浩器,它是类里的一种特殊的方法. 定义构浩器 构造器和通常方法的主要区别: (1)构浩器的名字必须和它所在的类的名字一样 (2)系统在创建某个类的实例时会第一时间自动调用这个类的构造器 (3)构浩器永远不会返回任何值 创建构浩器,需要先把它的声明添加到类里: class Car{ Car( voi

【iOS】Swift类的继承、构造方法、析构器等复习

构造方法内容会多一些,涉及Swift中构造的一些规则与概念.这次写了7个Person来复习,外加名人XiaoMing. Mark:Playground真是个好东西,特别练习写Swift时,实时显示真是大赞! 一.继承与重写, 防止重写 1.1 基类, 不继承任何类. Swift不想OC或者Java中继承自Object类.定义一个类,不继承任何类,该类就是基类. class Person1{ //这个Person1就是基类 func eat(){ println("eat a pig!"

C++ 类的继承三(继承中的构造与析构)

//继承中的构造与析构 #include<iostream> using namespace std; /* 继承中的构造析构调用原则 1.子类对象在创建时会首先调用父类的构造函数 2.父类构造函数执行结束后,执行子类的构造函数 3.当父类的构造函数有参数时,需要在子类的初始化列表中显示调用 4.析构函数调用的先后顺序与构造函数相反 继承与其他类做成员变量混搭的情况下,构造和析构嗲用原则 1.先构造父类,在构造成员变量,最后构造自己 2.先析构自己,再析构成员变量,最后析构父类 */ clas

【C++第十课】---继承中的构造与析构

一.继承中的赋值兼容性原则 1.子类对象可以当作父类对象使用 2.子类对象可以直接赋值给父类对象 3.子类对象可以直接初始化父类对象 4.父类指针可以直接指向子类对象 5.父类引用可以直接引用子类对象 6.子类是就是特殊的父类. 举例说明: #include <iostream> using namespace std; class Parent { protected: const char* name; public: Parent() { name= "Parent ...&q

Swift构造器(Initializer)与析构器(Deinitializer)

为了初始化结构体和类等类型的实例属性. 默认构造器 [html] view plaincopy struct Fahrenheit { var temperature: Doubleinit(){ temperature = 32.0 } } var f = Fahrenheit() //调用默认构造器 init() ,没有参数 没有返回值. [html] view plaincopy println("The default temperature   is \(f.temperature)°