C++的类与对象(三):构造函数、析构函数、对象的销毁顺序

news2024/9/29 17:38:10

目录

类的6个默认成员函数

构造函数

语法

特性

析构函数

特性

对象的销毁顺序​​​​​​​​​​​​​​


类的6个默认成员函数

问题:一个什么成员都没的类叫做空类,空类中真的什么都没有吗?

基本概念:任何类在什么都不写时,编译器会自动生成以下六个默认成员函数(无参的)

定义:用户没有显式实现,编译器会生成的成员函数称为默认成员函数

注意事项:如果我们自己实现了这些函数,那么编译器就不会生成默认的成员函数 

构造函数

产生原因:初始化容易被遗忘,且有时候会太麻烦

作用:完成初始化工作(Init)

class Date
{
public:
     void Init(int year, int month, int day)
     {
         _year = year;
         _month = month;
         _day = day;
     }

     void Print()
     {
         cout << _year << "-" << _month << "-" << _day << endl;
     }

private:
     int _year;
     int _month;
     int _day;
};

int main()
{
 Date d1;
 d1.Init(2022, 7, 5);
 d1.Print();
 Date d2;
 d2.Init(2022, 7, 6);
 d2.Print();
 return 0;
}

        对于Data类,之前我们会通过Init公有方法给对象设置日期,但每次创建对象时都需要调用该方法设置信息就显得有点麻烦,C++的构造函数就可以做到在对象创建时,就将信息设置进去

语法

1、构造函数是特殊的成员函数

2、构造函数的主要任务是在类实例化对象时初始化对象,而不是去开空间创建对象

3、构造函数的函数名与所在类的类名相同(类名是A,构造函数的名字就叫A,客随主便)

4、构造函数无返回值(不是void,而是连void都没)

5、对象实例化时编译器会自动调用合适的构造函数(对象后没括号就调无参构造函数,有实参就调用带参构造函数)

#include <iostream>
using namespace std;

 class Date
 {
  public:
      // 1.无参构造函数
      Date()
     {
        _year = 1;
        _month = 1;
        _day = 1;
     }

      void Print()
     {
        cout << _year << "-" << _month << "-" << _day << endl;
     }

  private:
      int _year;
      int _month;
      int _day;
 };

int main()
{
    Date d1; // 调用无参构造函数
    d1.Print();
    return 0;
}

6、构造函数可以重载

#include <iostream>
using namespace std;

class Date
{
public:
    // 1.无参构造函数
    Date()
    {
        _year = 1;
        _month = 1;
        _day = 1;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }
    // 2.带参构造函数
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1; // 调用无参构造函数
    d1.Print();

    Date d2(2015, 1, 1); // 调用带参的构造函数
    d2.Print();
    return 0;
}

7、构造参数没有形参时,对象实例化时不能在对象后加括号

8、 对象实例化时必须调用构造函数,没有或者没有合适的构造函数就会报错(d1原本想要调用无参的构造函数,但是只有带参的构造函数,有了带参的构造参数编译器就算像提供不带参的默认构造参数也没办法了)

#include <iostream>
using namespace std;

class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

    //带参构造函数
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

9、无参的构造函数和全缺省的构造函数在语法上因为函数重载可以同时存在,但是在实践中不可以,会造成调用歧义

#include <iostream>
using namespace std;

class Date
{
public:

    Date()
    {
        _year = 1;
        _month = 1;
        _day = 1;
    }
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

特性

1(重点)、实例化对象时我们不写构造函数(包括默认构造函数和普通的构造函数),编译器就会生成默认构造函数,从而初始化对象,我们写了构造参数编译器就不会生成默认构造参数(普通的构造参数是指带参的构造参数)

2、编译器生成的默认构造参数什么也不干,为什么?(我们程序员没有定义一个构造参数是我们的问题,但是你编译器既然为我们自动生成了一个默认构造参数,你总得让它起点作用吧,就是只让成员变量初始化为0也行啊)

#include <iostream>
using namespace std;

class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

这是因为,C++将数据分为了内置(基本)类型和自定义类型:

  • 内置类型:语言自身定义的类型(int、char、double、任何类型的指针等)
  • 自定义类型:程序员根据自己需求定义的类型(struct、class等)

3、C++98规定编译器生成的默认构造函数(程序员没提过时),对内置类型不做处理,对自定义类型会去调用它的!!默认构造函数!!(一定是默认构造函数而不是普通的构造函数)

#include <iostream>
using namespace std;

//编译器对自定义类型会调用它的默认构造
class A
{
public:
    A()
    {
        cout << "A()" << endl;
        _a = 0;
    }
private:
    int _a;

};

//编译器对内置类型不做处理
class Date
{
public:

//这里没有自定义构造函数,编译器默认生成构成函数

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

private:
    int _year;
    int _month;
    int _day;

    A _aa;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

大致步骤如下:
①Date d1:实例化对象d1

②Data{}:编译器自动生成默认构造函数,并开始对成员变量开始初始化 

③__aa:_aa的类型是A类,属于自定义类型,调用A类的提供的!默认!构造函数

如果A类也没提供默认构造函数,那么_aa也是随机值(虽然编译器也可以为A提供但是没用):

#include <iostream>
using namespace std;

class A
{
public:
    int getA() // 添加一个公共方法以获取 _a 的值
    {
        return _a;
    }

private:
    int _a;

};

class Date
{
public:

    void Print()
    {
        cout << "Year: " << _year << ", Month: " << _month << ", Day: " << _day << endl;
        cout << "Value of '_aa' member variable in class 'Date': " << _aa.getA() << endl; // 打印_aa对象内部_a变量的值
    }

private:
    int _year;
    int _month;
    int	_day;

    A _aa;
};


int main()
{
    Date d1;
    d1.Print();
    return 0;
}

④_year、_month、_day:是int类型,属于内置类型,不做任何操作,结果为随机值

为什么在调试时,先初始化对象_aa?

答:C++中,类的成员变量初始化顺序是由它们在类中声明的顺序决定的,而不是由它们在构造函数初始化列表中出现的顺序决定

注意事项:有些新的编译器会对内置类型也做处理,但是C++的标准没有规定 

4、C++11规定内置类型的成员变量声明时可给默认值(为C++98打补丁,没给的依然是随机值)

#include <iostream>
using namespace std;

class A
{
public:
    A()
    {
        cout << "A()" << endl;
        _a = 0;
    }

private:
    int _a;

};

class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

private:
    //声明时给缺省值
    int _year = 2024;
    int _month =3 ;
    int _day;

    A _aa;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

5、 只有无参 / 全缺省构造函数、编译器默认生成的构造函数都叫默认构造函数,其余的都是构造函数而不是默认构造函数,默认构造函数只能有一个 

//默认构造参数只能有一个:
#include <iostream>
using namespace std;
class Date
{
public:
    //无参的构造函数是默认构造函数
    Date()
    {
        _year = 1900;
        _month = 1;
        _day = 1;
    }

    //全缺省的构造函数是默认构造函数
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
private:
    int _year;
    int _month;
    int _day;
};

int main()
{
    Date d1;
    return 0;
}

//成员变量在声明时未给缺省值
#include <iostream>
using namespace std;
class Date
{
public:

    Date(int year = 1, int month , int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

     ~Date()
    {
         cout << this << endl;
         cout << " ~Date()" << endl;
    }

private:
    int _year;
    int _month;
    int _day;

};

int main()
{
    Date d1;
    d1.Print();

    return 0;
}

//成员变量在声明时提供缺省值:
#include <iostream>
using namespace std;
class Date
{
public:

    Date(int year = 1, int month , int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

     ~Date()
    {
         cout << this << endl;
         cout << " ~Date()" << endl;
    }

private:
    int _year = 1;
    int _month = 1;
    int _day =1;
};

int main()
{
    Date d1;
    d1.Print();
    return 0;
}

为什么成员变量在声明时已经给了缺省值,为什么Data还要再给?

虽然为 Date 类中的私有成员变量 _year_month, 和 _day 提供了默认值(1, 1, 1),但这些缺省值仅在默认构造函数未初始化成员变量时才会被用于初始化成员变量。实例化d1时,类中定义了一个貌似是全缺省的构造函数,因此编译器不会自动生成默认构造函数(那个位置上已经有人了,只是那个人有点缺陷),且因为该貌似的全缺省构造函数缺少两个缺省值所以报错

#include <iostream>
using namespace std;

class Time
{
public:
    //带参构造函数,不是默认构造函数
    Time(int hour)
    {
        cout << "Time()" << endl;
        _hour = 0;
        _minute = 0;
        _second = 0;
    }
private:
    int _hour;
    int _minute;
    int _second;
};

class Date
{
private:
    //声明给缺省值
    int _year;
    int _month;
    int _day;

    Time _t;
};

int main() 
{
    Date d;
    return 0;
}

为什么会提示_t没有默认构造函数?

答:实例化对象d时,Date类没给构造函数,编译器自动生成默认构造函数(无参),_year、_month、_day是内置类型不做处理,_t是自定义类型会调用Time类的默认构造函数,但是Time类中已经有了一个带参的构造函数(普通构造函数)所以Time类中不会有默认构造函数了(只要我们写了构造函数,即使它是带参的普通构造函数,编译器就不会给我们提供默认构造参数了)故报错

 结论:绝大多数场景下都需要自己实现构造函数,且更推荐用全缺省构造函数​​​​​​​

析构函数

 产生原因:需要人为销毁的空间容易忘记销毁,内存泄漏可能不会报错

#include <iostream>
using namespace std;
class Date
{
public:
    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }

    ~Date()
    {
        cout << this << endl;
        cout << " ~Date()" << endl;
    }

private:
    //声明给缺省值
    int _year = 1;
    int _month = 1;
    int _day = 1;

};

void func()
{
    Date d2;
}

class Stack
{
public:
    Stack(size_t capacity = 4)
    {
        _array = (int*)malloc(sizeof(int*) * capacity);
        if (NULL == _array)
        {
            perror("malloc申请空间失败!!!");
            return;
        }
        _capacity = capacity;
        _size = 0;
    }
    void Push(int data)
    {
        // CheckCapacity();
        _array[_size] = data;
        _size++;
    }

    //~Stack()
    //{
    //    cout << "~Stack()" << endl;
    //    if (_array)
    //    {
    //        free(_array);
    //        _array = nullptr;
    //    }
    //    _size = _capacity = 0;

    //}

private:
    int* _array;
    int _capacity;
    int _size;
};

int main()
{
    func();
    Date d1;
    Stack st1; //内存泄漏
    return 0;
}

        如果Stack类中没有自定义的析构函数就会出现内存泄漏,因为我们即没有定义Destory函数去销毁在堆上开辟的空间,析构函数也不起作用

作用:完成清理工作(Destory)

基本概念:析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的,而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

特性

1、析构函数名是在类名前加上字符~

2、析构函数无参数无返回值类型

3、一个类只能有一个析构函数,若未显示定义,编译器会自动生成默认的析构函数

4、析构函数不能重载(清理一遍数据就应该被清理完成)

5、对象生命周期结束(函数结束)时,程序会自动调用析构函数

#include <iostream>
using namespace std;
class Date
{
public:

     ~Date()
    {
         cout << this << endl;
         cout << " ~Date()" << endl;
    }

private:
    //声明给缺省值
    int _year = 1;
    int _month = 1;
    int _day =1;
};

void func()
{
    Date d2;//实例化对象d2
}//函数结束,调用析构函数销毁数据

int main()
{
    func();  
    Date d1;//实例化对象d1
    return 0;
}//函数结束,调用析构函数销毁数据

6、编译器生成的析构函数,对内置成员变量不做处理,对自定成员变量会调用它的析构函数

#include <iostream>
using namespace std;

class Time
{
public:
	~Time()
	{
		cout << "~Time()" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};

class Date
{
private:
	// 基本类型(内置类型)
	int _year = 1970;
	int _month = 1;
	int _day = 1;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

在main函数中没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?

答:main函数中创建了Date类的对象d,d中包含了四个成员变量,其中_year、_month、_day是内置类型的成员变量,销毁时不需要人为清理资源main函数结束后系统直接回收,而_t是Time类的对象,为了销毁_t就需要Data类的析构函数,但是我们并没有给Date类定义析构函数,所以编译器就会为Date类提供一个默认析构函数,该函数对于自定义类型的成员变量就会调用它(_t)的析构函数(Time提供的析构函数)

7、后定义的先析构(定义->开辟帧栈->压栈,栈后进先出)

#include <iostream>
using namespace std;
class Date
{
public:
    ~Date()
    {
        cout << this << endl;
        cout << " ~Date()" << endl;
    }

private:
    //声明给缺省值
    int _year = 1;
    int _month = 1;
    int _day = 1;

};

class Stack
{
public:
    Stack(int capacity = 4)
    {
        _array = (int*)malloc(sizeof(int*) * capacity);
        if (NULL == _array)
        {
            perror("malloc申请空间失败!!!");
            return;
        }
        _capacity = capacity;
        _size = 0;
    }
    void Push(int data)
    {
        // CheckCapacity();
        _array[_size] = data;
        _size++;
    }

    ~Stack()
    {
        cout << this << endl;
        cout << "~Stack()" << endl;
        if (_array)
        {
            free(_array);
            _array = nullptr;
        }
        _size = _capacity = 0;

    }
private:
    int* _array;
    int _capacity;
    int _size;
};

int main()
{
    Date d1;
    Stack st1;
    return 0;
}

 8、如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数(Date类);有资源申请时,一定要写,否则会造成资源泄漏(Stack类)

 9、自定义类型的本质还是内置类型

对象的销毁顺序

从左至右:局部变量(后定义的先析构)——>局部的静态——>全局(后定义的先析构)

当成栈来理解,先进后出 

#include <iostream>
using namespace std;
class Date
{
public:
    //全缺省构造函数
    Date(int year = 1)
    {
        _year = year;
    }

    ~Date()
    {
        cout << " ~Date()->" << _year << endl;
    }

private:
    //声明给缺省值
    int _year;
    int _month;
    int _day;

};

Date d5(5);//全局
Date d6(6);//全局
static Date d7(7);//全局
static Date d8(8);//全局

void func()
{
    Date d3(3);//局部
    static Date d4(4);//局部的静态
}

int main() 
{
    Date d1(1);//局部
    Date d2(2);//局部
    func();
    return 0;
}


#include <iostream>
using namespace std;
class Date
{
public:
    //全缺省构造函数
    Date(int year = 1)
    {
        _year = year;
    }

    ~Date()
    {
        cout << " ~Date()->" << _year << endl;
    }

private:
    int _year;
    int _month;
    int _day;

};

int main()
{
    Date d1(1);//局部
    Date d2(2);//局部
    static Date d3(3);//局部的静态
    return 0;
}


~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1506350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用swagger生成接口文档

使用swagger生成接口文档 有时候一份清晰明了的接口文档能够极大地提高前后端双方的沟通效率和开发效率。本文将介绍如何使用swagger生成接口文档。 swagger生成接口文档 swagger介绍 Swagger本质上是一种用于描述使用JSON表示的RESTful API的接口描述语言。Swagger与一组开…

MT笔试题

前言 某团硬件工程师的笔试题&#xff0c;个人感觉题目的价值还是很高的&#xff0c;分为选择题和编程题&#xff0c;选择题考的是嵌入式基础知识&#xff0c;编程题是两道算法题&#xff0c;一道为简单难度&#xff0c;一道为中等难度 目录 前言选择题编程题 选择题 C语言中变…

突破编程_前端_JS编程实例(目录导航)

1 开发目标 目录导航组件旨在提供一个滚动目录导航功能&#xff0c;使得用户可以方便地通过点击目录条目快速定位到对应的内容标题位置&#xff0c;同时也能够随着滚动条的移动动态显示当前位置在目录中的位置&#xff1a; 2 详细需求 2.1 标题提取与目录生成 组件需要能够自…

【PHP+代码审计】PHP基础——运算符

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

数据分析-Pandas两种分组箱线图比较

数据分析-Pandas两种分组箱线图比较 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&am…

【prompt四】Domain Prompt Learning for Efficiently Adapting CLIP to Unseen Domains

motivation 领域泛化(DG)是一个复杂的迁移学习问题,旨在学习未知领域的可泛化模型。最近的基础模型(FMs)对许多分布变化都具有鲁棒性,因此,应该从本质上提高DG的性能。在这项工作中,我们研究了采用视觉语言基础模型CLIP来解决图像分类中的DG问题的通用方法。虽然ERM使用标…

【设计模式】(四)设计模式之工厂模式

1. 工厂模式介绍 工厂模式&#xff08;Factory Pattern&#xff09;是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 工厂模式有三种实现方式&#xff1a; 简单工厂模式工厂方法模式抽象工厂模式 2. 工厂方…

部署LVS+Keepalived高可用群集(抢占模式,非抢占模式,延迟模式)

目录 一、LVSKeepalived高可用群集 1、实验环境 2、 主和备keepalived的配置 2.1 yum安装ipvsadm和keepalived工具 2.2 添加ip_vs模块并开启ipvsadm 2.3 修改keepalived的配置文件 2.4 调整proc响应参数&#xff0c;关闭linux内核的重定向参数响应 2.5 将主服务器的kee…

SSRF服务器请求伪造原理和pikachu靶场实验

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、SSRF简介 SSRF全称&#xff1a;Server-Side Request…

深入理解操作系统Operator System(2)

目录 操作系统对上的管理 系统调用接口 用户操作接口&#xff08;库函数&#xff09; 系统调用和库函数的概念 结构层次示意图 总结 为什么要有操作系统❓ 上次主要介绍了操作系统的"管理"和操作系统对下的管理。本篇主要是对上的管理。 操作系统对上的管理 …

【运维】本地部署Gemma模型(图文)

工具简介 我们需要使用到两个工具&#xff0c;一个是Ollama&#xff0c;另一个是open-webui。 Ollama Ollama 是一个开源的大语言平台&#xff0c;基于 Transformers 和 PyTorch 架构&#xff0c;基于问答交互方式&#xff0c;提供大语言模型常用的功能&#xff0c;如代码生…

软考高级:电子商务角色和类型概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

个人网站展示(静态)

大学期间做了一个个人博客网站&#xff0c;纯H5编码的网站&#xff0c;利用php搭建了一个留言模块。 有需要源码的同学&#xff0c;可以联系我~ 首页&#xff1a; IT杂记模块 文人墨客模块 劳有所获模块 生活日志模块 关于我 一个推崇全栈开发的前端开发人员 微信: itrzzh …

人工智能时代的产品管理:如何成为下一代引领者

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

字符串标记高亮脚本

源码 #!/bin/bash # usage: # echo hhh|mark str [font_color] [background_color] # font_color and background_color is optional, default is black&whiterp_str$1 f_color30 b_color47if [ "${f_color}a" "a" ]; thenf_color30 fiif [ "${…

网络安全: Kali Linux 进行 MSFvenom 程序利用

目录 一、实验 1.环境 2. Kali Linux 进行 MSFvenom 程序利用 3. 创建计划任务自动运行 MSFvenom 程序 二、问题 1.在线加密解密 2.MSF 运行失败 3.MobaXterm 连接Ubuntu 失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统版本IP备注Kali Linux20…

ElasticSearch之排序,fielddata和docvalue

写在前面 es搜索返回结果的排序默认是按照得分的高低来排的&#xff0c;本文来看下如何按照字段来排序&#xff0c;实现类似于MySQL的order by xxx的效果。 1&#xff1a;什么是fileddata和doc_value 参考ElasticSearch之零碎知识点 和一文带你彻底弄懂ES中的doc_values和fi…

直击Spring源码——高级容器

高级容器都实现了ApplicationContext功能&#xff0c;平常说的上下文就是高级容器 public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver { …

【笔记】原油阳谋论

文章目录 石油的属性能源属性各国石油替代 金融属性黄金石油美元 油价历史油价传导路径 石油供需格局与发展供需格局各国状况美国俄罗斯沙特 产油国困境运输 分析格局分析供需平衡分析价差分析价差概念基本面的跨区模型跨区模型下的价差逻辑 长中短三期分析长期视角——供应看投…

【CSS面试题】高度塌陷问题及解决

什么情况下产生 (when 父盒子没有定义高度&#xff0c;但是子元素有高度&#xff0c;希望用子盒子撑起父盒子的高度&#xff0c;但是子盒子添加了浮动属性之后&#xff0c;父盒子高度为0 <template><div class"father"><div class"son"&…