lesson03:类和对象(中)

news2024/9/20 2:56:15

1.类的6个默认的成员函数

2.构造函数

3.析构函数

4.拷贝构造函数

1.类的6个默认的成员函数

空类(类中一个成员都没没有)会有成员函数吗?

其实是有的!如果我们在类中什么都不写,编译器会自动生成6个默认成员函数(用户什么都不写,编译器自动生成的函数叫默认成员函数)。

它们分别是:

1.构造函数

2.析构函数

3.拷贝构造函数

4.赋值运算符重载函数

5.取地址操作符重载函数

6.const取地址操作符重载函数

2.构造函数

2.1定义

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
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;
}

构造函数是一个特殊的成员函数,是用来给对象的数据成员初始化的。(用处类似于上面的自定义成员函数Init,注意:这个Init不是构造函数!)

2.2特性

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	// 1.无参构造函数
	Date()
	{}

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

void TestDate()
{
	Date d1; // 调用无参构造函数
	Date d2(2015, 1, 1); // 调用带参的构造函数
}

int main()
{
	TestDate();
	return 0;
}

构造函数是特殊的成员函数,构造函数虽然叫构造函数,但它不是用来开空间创建对象的,而是用来初始化对象的。

1.构造函数函数名和类名相同

2.构造函数无返回值,也不用在定义时写返回值类型(简单的来说,连void都不要写,返回值类型直接空着)

3.实例化对象时编译器自动调用构造函数。(这一步是一定进行的,实例化对象时一定会调用构造函数),在对象整个生命周期内只能调用一次(在创建对象的时候必须调用一次,所以不能显示调用构造函数)。

4.构造函数可以重载。

5.在自定义函数TestDate中:

5.1因为d1后面什么都没写,所以实例化(创建)对象d1时,编译器将调用无参构造函数或全缺省构造函数,也就是第一个构造函数。

那为什么只能调用这两种呢?

解答:因为没有传递参数,其他种类的构造函数都要传参数啊。

5.2因为d2后面在括号里写了三个参数(不要问为什么这么写,这是规定),这两个参数将传递给构造函数,所以将调用需传递两个参数的构造函数,也就是第二个函数。

那为什么不能调用给其他的构造函数呢?

解答:以无参构造函数为例,也就是第一个构造函数,他没有形参去接受这两个参数。

那么一般的多参构造,以有4个参数的构造函数为例,它也是不可以的,传递的参数不够。

5.3那么所有的多参构造都不可以吗?

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	// 1.无参构造函数
	Date()
	{}

	// 2.带参构造函数
	Date(int year, int month, int day, int n = 5)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d(1, 2, 3);
	return 0;
}

解答:其实不是的,像上面这样的半缺省构造函数可以只传三个参数,那么它就是可以的。

注意:看第8行和第12行,构造函数函数名前什么都不写,不要写类型

	Date d3();

注意:如果实例化对象时不给构造函数传参,一定不能写小括号。

这个是函数的声明,如果实例化对象这样写,无法和函数声明区分!

	Date d3(1, 2, 3);

但是,像这样给构造函数传参的,是可以写小括号的,函数声明要写明类型,而上面的代码没有写类型,所以这里是可以和函数声明区分开的。

6.如果用户显示定义了构造函数(就是你自己写了构造函数),编译器将不会生成默认构造函数(默认构造也没有形参,属于一种无参构造)。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
};

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

前面说过,实例化(创建)对象时编译器一定会自动调用构造函数,但是这里我们没有定义构造函数,会不会报错呢?

答案是不会的,Date类中有一个构造函数,它由编译器生成,我们是看不见的。在实例化d3时调用的是这个由编译器生成的构造函数,这个默认生成的构造函数是无参构造函数,不需要传参。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date (int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};

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

这段代码是编不过去的,为什么错了呢?编译器不是会生成默认的无参构造函数吗?

解答:要注意,由于我们自己定义了构造函数,编译器就不再生成默认构造函数了!现在只有一个要传三个参数的构造函数,必须传三个参数。 

7.默认构造函数能干什么呢?

#define _CRT_SECURE_NO_WARNINGS
#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 d3;
	d3.print();
	return 0;
}

在visual studio 2022社区版上,上面的代码运行后,输出的是随机值,所以默认构造函数貌似没有初始化的功能,那么这个默认构造函数有什么用呢?

解答:c++把类型分为了内置类型(编译器自带的,如int,char等)和自定义类型(自己定义的,如类类型,结构体类型等,注意:凡是指针类型都是内置类型,如类指针类型,结构体指针类型也是内置类型),默认构造函数会自动调用自定义类型成员的构造函数

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Time
{
public:
	Time()
	{
		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;
}

这里打印了“Time()”,说明自定义类型成员_t的无参构造函数确实被调用了。

总结:在实例化(创建)对象时,构造函数对内置类型成员不作处理,对自定义类型成员调用它的无参构造函数。

补充:由于标准未说明不允许对内置类型作处理,所以有些编译器会对内置类型作处理;但是标准也未说明一定要对内置类型作处理,有些编译器是不会对内置类型作处理的。

8.考虑到函数重载和调用歧义问题,无参构造和全缺省构造的总数最好不要超过1个

#define _CRT_SECURE_NO_WARNINGS
#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;
};
// 以下测试函数能通过编译吗?
void Test()
{
	Date d1;
}
int main()
{
	Test();
	return 0;
}

如这里在实例化d1时,因为d1后面什么都没写,所以编译器要调用d1的无参构造函数或全缺省构造函数,由于这样的函数有两个,编译器不知道用哪个,所以这里就报错了。

#define _CRT_SECURE_NO_WARNINGS
#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;
};
// 以下测试函数能通过编译吗?
void Test()
{
	Date d1(1);
}
int main()
{
	Test();
	return 0;
}

但是如果我们在实例化对象d1时传一个参数,就可以躲过调用歧义,就可以编过去了,但是极度不建议这么写!!!

9.如果实例化(创建)对象时,当中有自定义类型成员,且该成员所对应的类没有无参构造或全缺省构造,编译器会直接报错。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Time
{
public:
	Time(int a)
	{
		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;
}

 但是,自定义类型成员并不是必须是含有无参构造函数或全缺省构造函数的对象,后面会讲到初始化列表,可以解决这个问题。

可能很多小伙伴已经想到办法了,像下面这样写不就行了?

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Time
{
public:
	Time(int a)
	{
		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(1);
};
int main()
{
	Date d;
	return 0;
}

 要注意啊,Time _t(1);这种写法是定义对象,类的声明中是不能定义数据对象或变量的,不过在类的成员函数的定义中是可以定义对象或变量的。

3析构函数

3.1概念

析构函数与构造函数的功能相反,构造函数不是创建对象的,析构函数也不是销毁对象的,析构函数的作用是完成对象中资源的清理工作,在对象生命周期结束时由函数自动调用

3.2特性

1.析构函数名就是在类名前加上~

2.无参数,无返回值类型(这里和构造一样,连void也不要写)

3.一个类只能有一个析构函数(因为析构函数没有参数,无法实现重载),若未显式定义,编译器会自动生成默认析构函数

4.对象生命周期结束时编译器自动调用析构函数。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	Date()
	{
		cout << "Date()" << endl;
		_year = 1900;
		_month = 1;
		_day = 1;
	}
	~Date()
	{
		cout << "~Date()" << endl;
		_year = 0;
		_month = 0;
		_day = 0;
	}
private:
	int _year;
	int _month;
	int _day;
};
void test()
{
	Date d;
}
int main()
{
	test();
	return 0;
}

对象d是在test函数中定义的局部变量,出函数后,自动调用析构函数;在这里,主函数并未结束,但已经调用了对象d的析构函数,可见,对象的析构函数不是一定在主函数结束时调用的。

5.默认的析构函数和默认的构造函数类似,对内置类型不做处理,对自定义类型自动调用它的析构函数。

补充:构造函数都会对自定义类型成员调用它的构造函数;析构函数都会对自定义类型成员调用它的析构函数。这样的特性并不是默认构造和默认析构所特有的,自定义的也有。

6.如果类中没有申请资源(如申请空间,打开文件等),析构函数没必要写,直接使用编译器生成的默认析构函数;有资源申请时一定要写,否则会造成内存泄漏等问题。

4.拷贝构造函数

4.1概念

拷贝构造函数时一个特殊的构造函数,主要体现在形参不同,它的作用也是初始化对象,它也拥有构造函数的特性(它也能对自定义类型成员自动调用它的构造)。

4.2特性

1.拷贝构造函数是构造函数的一个重载

2.拷贝构造函数只有一个形参,且一定是本类类型的引用,使用传值传参编译器会报错,因为会引发无穷递归。

3.拷贝构造函数不仅可以用普通构造函数的方式使用,而且可以用初始化普通变量的方式使用(如int型变量,char型变量等),如下图。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//Date(const Date d)//错误写法:编译报错,会引发无穷递归
	Date(const Date& d)// 正确写法
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void print()
	{
		cout << _year << ' ' << _month << ' ' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d2(2024, 4, 19);
	//Date d1(d2);与Date d1 = d2;是等价的,一般情况下写第二种,意思更加明确
	//Date d1(d2);
	Date d1 = d2;
	d1.print();
	return 0;
}

注意:

Date d1;
Date d2;
d2 = d1;

向这样分开写用的就不是拷贝构造函数了,而是使用了默认赋值运算符重载函数(后面会讲)。

3.若未显式定义拷贝构造函数,编译器会生成默认的拷贝构造函数

那默认的拷贝构造也和默认的构造一样吗?也是对内置类型不做处理吗?

解答:默认的拷贝构造函数会将参数按内存存储按字节序完成拷贝,这种拷贝叫浅拷贝,也叫值拷贝。顾名思义,就是将数据成员的值拷贝过去。

4.编译器生成的默认拷贝构造已经能完成拷贝了,还要显式实现吗?

解答:看情况,例如以下的就需要。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class arr
{
private:
	int* a;
public:
	arr()
	{
		a = (int*)malloc(10 * sizeof(int));
	}
};
int main()
{
	arr a1;
	arr a2 = a1;
	return 0;
}

可以看到,对象a1和对象a2中数据成员,也就是指针变量a是一样的,两个指针指向了同一块空间,这不是我们想要的,我们希望的是让编译器再开一块空间的。

有人就要问了,这也拷贝成功了,有什么不妥吗?

解答:这两个对象的指针变量a指向的是同一块空间,它们是共用这块空间的,会相互影响的。

所以这里需要我们显式写拷贝构造函数,手动开空间,完成深拷贝。

5.拷贝构造函数典型调用场景:

场景一:使用已存在对象创建新对象

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		cout << "Date()" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._day;
		_month = d._month;
		_day = d._day;
	}
};
void test(Date d)
{

}
int main()
{
	Date d;
	Date d1 = d; //使用已存在对象创建新对象
	return 0;
}

场景二:函数传参时传递对象

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		cout << "Date()" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._day;
		_month = d._month;
		_day = d._day;
	}
};
void test(Date d)
{

}
int main()
{
	Date d;
	test(d); //使用已存在对象创建新对象
	return 0;
}

场景三:函数返回值返回对象

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		cout << "Date()" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._day;
		_month = d._month;
		_day = d._day;
	}
};
Date test(Date d)
{
	return d;//函数返回值返回对象
}
int main()
{
	Date d;
	test(d); //使用已存在对象创建新对象
	return 0;
}

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

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

相关文章

HTML的学习-通过创建相册WEB学习HTML-第二部分

文章目录 二、学习开始3.6、form元素示例&#xff1a;添加form元素示例&#xff1a;action属性添加到form属性中 3.7、input元素示例&#xff1a;在input属性中添加参数 3.8、button元素示例&#xff1a;在button中添加type元素示例&#xff1a;定义单选按钮radio 3.9、id属性示…

时序分析基础(6)——input delay时序分析

1 简介 FPGA对于外部的时钟以及数据的延时信息是不知道的&#xff0c;在低速时钟且时钟发射沿在数据正中心的时候&#xff0c;一般可以不做约束来直接使用。但是到了高速时钟或者双沿采样或者发射沿和数据对齐的情况下&#xff0c;这时候就需要告诉VIVADO外部的时钟与数据情况来…

[2021最新]大数据平台CDH存储组件kudu之启用HA高可用(添加多个master)

今天在做kudu高可用的时候没有参考官网&#xff0c;直接按照常规方式&#xff08;添加角色—>编辑属性—>启动&#xff09;结果发现报错&#xff1f;然后参考了一下文档之后发现这玩意儿还有点玄学&#xff0c;做一下记录。 1.添加两个master。kudu master有leader和foll…

革命性创新,实景AI无人自动直播系统,轻松实现24小时日不落直播卖券。

革命性创新&#xff01;实景AI无人自动直播系统&#xff0c;轻松实现24小时日不落直播卖券&#xff01; 最近&#xff0c;越来越多的朋友纷纷关注到了AI自动直播带货的新玩法&#xff0c;并且也都想要开设自己的自动直播间。然而&#xff0c;对于这种自动讲解、自动回复的直播…

docker-003镜像制作

步骤 使用docker commit提交容器使之成为镜像以ubuntu安装vim后的容器为例 1 ubuntu安装vim 启动容器 docker run -it --nameubuntu-vim ubuntu /bin/bash安装vim apt-get update apt-get install vim2 提交容器作为镜像 查看容器 docker ps -a提交容器作为镜像 命令格式&…

js 打印网页时没有背景色,window.print打印背景色丢失

页面效果 打印效果 需要在打印的容器里增加下面代码 /*webkit 为Google Chrome、Safari等浏览器内核*/ -webkit-print-color-adjust: exact; /*解决火狐浏览器打印*/ print-color-adjust: exact; color-adjust: exact; 完整写法 我为了方便直接写*&#xff0c;这样所有元素都…

如何设置unbuntu时间及同步时间

文章目录 时区时间同步与服务 时间同步的重要性Ubuntu系统中设置时间和同步时间方法一&#xff1a;通过图形界面设置查看当前时间设置时间和时区设置时区&#xff08;假设设置为UTC&#xff09;&#xff1a;设置本地时间&#xff08;例如&#xff0c;设置时间为2024年4月21日 1…

23.组件注册方式

组件注册方式 一个 Vue 组件在使用前需要先被“注册”&#xff0c;这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式&#xff1a;全局注册和局部注册 全局注册 import { createApp } from vue import App from ./App.vue import GlobalComponent from ".…

【C++】STL:vector常用接口的使用和模拟实现

Hello everybody!这篇文章主要给大家讲讲vector常用接口的模拟实现&#xff0c;STL库中的实现一层套着一层&#xff0c;十分复杂&#xff0c;目前阶段还不适合看源代码。而模拟实现可以让我们从底层上了解这些接口的原理从而更好的使用这些接口。另外我还会讲一些在vector使用过…

OSPF的学习笔记

1.OSPF &#xff08;1&#xff09;链路状态路由协议的路由信息并不是像距离矢量路由协议那样(邻居告诉的)&#xff0c;通过收集自身以及邻居发出的LSA(原材料)&#xff0c;并LSA放到指定仓库里面(LSDB)&#xff0c;通过SPF算法&#xff0c;以自己为根计算到达网络每个节点的最优…

LeetCode刷题实战5:最长回文子串

题目内容 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab" 解释&#xff1a;"aba"…

虚拟线程的定义及使用

0.前言 长期以来&#xff0c;虚拟线程是 Java 中最重要的创新之一。 它们是在 Project Loom 中开发的&#xff0c;自 Java 19 作为预览功能以来一直包含在 JDK 中&#xff0c;自 Java 21 作为最终版本 (JEP 444) 以来&#xff0c;它们已包含在 JDK 中。 1.虚拟线程的作用 任…

深入OceanBase内部机制:资源隔离实现的方式总结

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 1. 为何HTAP需要资源隔离2. OceanBase的资源隔离机制概述租户间资源隔离租户内资源隔离物理资源隔离大查询请求的隔离优先级…

如何批量给Word文件增加前缀序号?“汇帮批量重命名”帮助你批量给word文件增加前缀序号。

批量给Word文件增加前缀序号的过程&#xff0c;对于经常处理大量文档的人来说&#xff0c;是一项既繁琐又必要的任务。首先&#xff0c;我们需要明确为什么要给Word文件增加前缀序号。在很多情况下&#xff0c;当我们需要按照一定的顺序对多个文档进行管理和归档时&#xff0c;…

【CSS】CSS实现元素逐渐消失(实现元素透明逐渐消失/模糊)

mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 10%);mask-image 属性用于定义一个遮罩&#xff0c;它可以隐藏元素的一部分或全部内容。在这个示例中&#xff0c;我们使用 mask-image 属性来定义一个线性渐变的遮罩&#xff0c;使得列表项的内…

适配器模式【结构型模式C++】

1.概述 适配器模式是一种结构型设计模式&#xff0c; 又称为变压器模式、包装模式&#xff08;Wrapper&#xff09; 将一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 2.结构 Target&#xff1a;适配…

Https网站接口被黑被恶意调取

背景&#xff1a; 维护的一个网站最近短信接口被黑&#xff0c;发送大量短信。起初以为是在网站内部操作&#xff0c;优化了发送短信前的操作&#xff0c;如添加图形验证码&#xff0c;屏蔽国外IP等。但后续还存在被调取情况&#xff0c;定位排查到是该接口在外部被恶意调取。 …

Pod 状态 Bsck Off,是什么情况?

k8s项目运维中&#xff0c;相信各位都遇到过 Pod 状态 Bsck Off 的情况&#xff0c;如上图&#xff1a;该情况主要原因是我们 Pod 中没有任何容器运行成功&#xff0c;而能容器能成功运行的前提是&#xff0c;容器内部是有进程的&#xff0c;只要容器中的进程不停止&#xff0c…

ATM第二弹~~~

昨天发现自己电脑的运行速度太慢的问题后&#xff0c;在autodl租了个4090 &#xff08;本来跑了4个小时快好了&#xff0c;但由于没有续上费&#xff0c;断了。。。。&#xff09; ( 2.58 每小时&#xff0c;贵死我了。。。。&#xff09; 又重新开了个4090d&#xff08;409…

论文笔记:Large Language Model for Participatory Urban Planning

202402 arxiv 大模型城市规划 引入了一个基于LLM的多代理协作框架&#xff0c;模拟规划师和数千名具有不同特征和背景的居民&#xff0c;用于参与式城市规划——>生成考虑居民多样化需求的城市区域土地利用规划为了提高讨论的效率&#xff0c;论文采用了鱼缸讨论机制&#…