[C++核心编程-06]----C++类和对象之对象模型和this指针

news2024/11/19 16:33:31

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页:@一伦明悦-CSDN博客

✍🏻 作者简介: C++软件开发、Python机器学习爱好者

🗣️ 互动与支持:💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论,点赞加收藏支持我,点击关注,一起进步!


目录

引言                   

正文

01-对象模型和this指针简介                   

02-成员变量和成员函数分开存储                   

03-this指针                   

04-空指针访问成员函数                  

总结                  


引言                   

        在C++中,类是一种用于描述一类对象的数据结构,而对象则是根据类定义创建的实例。类定义了对象的属性和方法,而对象是类的具体实例化。在C++中,类和对象一起构成了面向对象编程的基础。

        在C++中,对象模型是用来描述类和对象之间关系的一种模型。在C++中,每个对象都有自己的一组成员变量和方法,这些成员变量和方法定义在类中。当创建一个对象时,该对象会占用一些内存空间来存储其成员变量,并且会有一个指向类的指针,这个指针指向该对象所属的类。

        this指针是一个隐含的指针,它指向当前对象的地址。在类的成员函数中,可以使用this指针来访问当前对象的成员变量和方法。this指针的类型是指向当前类的指针。

正文

01-对象模型和this指针简介                   

        在C++中,对象模型和this指针是面向对象编程的两个重要概念,它们有助于理解类和对象之间的关系以及在类的成员函数中操作对象的方式。

        对象模型:

        对象模型是用来描述类和对象之间关系的一种模型,它包括了对象的内存布局和对象访问的机制。在C++中,每个对象都有自己的一组成员变量和方法,这些成员变量和方法定义在类中。当创建一个对象时,该对象会占用一些内存空间来存储其成员变量,并且会有一个指向类的指针,这个指针指向该对象所属的类。

        this指针:

        this指针是一个隐含的指针,它指向当前对象的地址。在类的成员函数中,可以使用this指针来访问当前对象的成员变量和方法。this指针的类型是指向当前类的指针。通过this指针,可以在成员函数中区分当前对象和其他对象。

        详细总结:

      (1)对象模型

        a、对象模型描述了类和对象之间的关系,包括对象的内存布局和访问机制。

        b、每个对象都有自己的一组成员变量和方法,这些成员定义在类中。

        c、创建对象时,会为其分配内存空间,并有一个指向类的指针。

       (2)this指针

         a、this指针是一个隐含的指针,在类的成员函数中自动被创建。

         b、this指针指向当前对象的地址,允许在成员函数中访问当前对象的成员变量和方法。

         c、可以用来区分当前对象和其他对象,在处理对象自身的操作时非常有  

        下面是一个简单的示例,展示了对象模型和this指针的使用:

        在上面的示例中,定义了一个名为MyClass的类,该类有一个成员变量value和两个成员函数setValue和printValue。在setValue函数中,使用this指针来设置当前对象的value值,在printValue函数中,使用this指针来打印当前对象的value值。

        在main函数中创建了两个MyClass的对象obj1和obj2,分别调用了setValue和printValue函数来设置和打印对象的value值。

        通过这个示例,可以看到类和对象之间的关系以及如何使用this指针来操作当前对象的成员变量和方法。

#include <iostream>

class MyClass {
public:
    int value;

    void setValue(int value) {
        this->value = value; // 使用this指针设置当前对象的value值
    }

    void printValue() {
        std::cout << "Value: " << this->value << std::endl; // 使用this指针打印当前对象的value值
    }
};

int main() {
    MyClass obj1;
    MyClass obj2;

    obj1.setValue(10);
    obj2.setValue(20);

    obj1.printValue(); // 打印obj1的value值
    obj2.printValue(); // 打印obj2的value值

    return 0;
}

02-成员变量和成员函数分开存储                   

        在C++中,成员变量和成员函数是分开存储的,这是为了提高内存的利用率和程序的执行效率。成员变量存储在对象的内存空间中,而成员函数则存储在类的代码段中,所有对象共享同一份成员函数的代码。

        成员变量存储:

        成员变量是属于对象的数据,每个对象都有自己的一份成员变量。当创建一个对象时,系统会为其分配内存空间来存储成员变量,这些成员变量的大小取决于其类型和数量。每个对象的成员变量存储在其所占用的内存空间中,不同对象的成员变量是相互独立的。

        成员函数存储:

        成员函数是属于类的行为,它们被定义在类的内部,但并不存储在对象的内存空间中。相反,成员函数的代码只存储了一份,它们被存储在类的代码段中。所有属于同一个类的对象共享同一份成员函数的代码,这样可以节省内存空间。

        详细解释:

        (1)成员变量存储

        a、成员变量是对象的数据,每个对象都有自己的一份成员变量。

        b、当创建对象时,系统会为其分配内存空间来存储成员变量。

        c、不同对象的成员变量存储在各自的内存空间中,彼此独立。

        (1)成员函数存储

        a、成员函数是类的行为,它们被定义在类的内部。

        b、成员函数的代码存储在类的代码段中,而不是存储在对象的内存空间中。

        c、所有属于同一个类的对象共享同一份成员函数的代码,这样可以节省内存空间。

        下面是一个简单的示例,展示了成员变量和成员函数的存储方式:在这个示例中,可以看到成员变量value存储在每个对象的内存空间中,而成员函数setValue和getValue的代码只存储了一份,它们被所有对象共享。

#include <iostream>

class MyClass {
public:
    int value; // 成员变量

    void setValue(int val) { // 成员函数
        value = val; // 访问成员变量
    }

    int getValue() { // 成员函数
        return value; // 返回成员变量的值
    }
};

int main() {
    MyClass obj1, obj2; // 创建两个对象

    obj1.setValue(10); // 设置对象1的值
    obj2.setValue(20); // 设置对象2的值

    std::cout << "Value of obj1: " << obj1.getValue() << std::endl; // 获取并打印对象1的值
    std::cout << "Value of obj2: " << obj2.getValue() << std::endl; // 获取并打印对象2的值

    return 0;
}

        下面给出具体的代码进行分析成员变量和成员函数的使用过程:

        这个示例展示了C++中成员变量和成员函数分开存储的情况。在这个示例中,定义了一个名为Person的类,其中包括了非静态成员变量m_A,静态成员变量m_B,非静态成员函数func和静态成员函数func1。

        在函数test01中创建了一个Person对象p,并使用sizeof操作符来输出对象p所占用的字节数。即使对象p是空的,C++编译器也会分配一个字节的空间来区分空对象的内存位置,确保每个对象都有一个独一无二的内存地址。

        在函数test02中再次创建了一个Person对象p,并输出其占用的字节数,结果应该和test01中的一样。

        通过这个示例可以看到,在C++中,即使是空对象也会占用一定的内存空间,同时也展示了成员变量和成员函数分开存储的情况。

#include <iostream>
using namespace std;

// 成员变量和成员函数分开存储
class Person
{
	int m_A;   // 非静态成员变量   属于类对象上
	static int m_B;  // 静态 不属于类对象上
	void func() {}  // 非静态成员函数,也不属于类对象上
	static void func1() {}  // 静态成员函数 不属于类对象上
};

void test01()
{
	Person p;
	// 空对象占用字节
	// C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象所占内存的位置
	// 每个空对象也应该有一个独一无二的内存地址
	cout << "size of p = " << sizeof(p) << endl;
}

void test02()
{
	Person p;
	cout << "size of p = " << sizeof(p) << endl;
}

int main()
{
	test02();

	system("pause");
	return 0;
}

        示例运行结果如下图所示:

03-this指针                   

        在C++中,this指针是一个隐含的指针,它指向当前对象的地址。this指针在类的成员函数中自动被创建,并且可以用来访问当前对象的成员变量和成员函数。通过this指针,可以在成员函数中区分当前对象和其他对象,从而实现对当前对象的操作。

        详细解释:

        (1)this指针的作用

        a、this指针指向当前对象的地址,允许在成员函数中访问当前对象的成员变量和成员函数。

        b、当多个对象同时存在时,this指针可以帮助区分当前对象和其他对象,确保操作的是正确的对象。

        (2)this指针的类型

        a、this指针的类型是指向当前类的指针,因此在成员函数中可以直接访问当前类的成员。

        b、在成员函数中,可以通过this->成员变量或this->成员函数的方式来访问当前对象的成员变量和成员函数。

       (3)this指针的隐含性

        a、在类的成员函数中,this指针是隐含的,不需要显式地声明或传递。

        b、当调用成员函数时,编译器会自动将当前对象的地址传递给this指针。

         接下来给出具体代码分析展示了this指针的使用:详细解释代码如下:

        这段代码演示了如何使用this指针在C++中访问对象的成员变量。在类MyClass中,定义了一个私有成员变量value和两个公有成员函数setValuegetValue。在setValue函数中,使用了this指针来设置当前对象的value值,而在getValue函数中,使用this指针来获取当前对象的value值。

        在main函数中,创建了两个MyClass对象obj1obj2,分别设置了它们的value值为10和20,并通过调用getValue函数获取并打印了它们的value值。

        这段代码展示了this指针的隐含性和作用,通过this指针可以在成员函数中准确地访问当前对象的成员变量,确保操作的是正确的对象。

#include <iostream>

class MyClass {
private:
    int value;

public:
    void setValue(int value) {
        this->value = value; // 使用this指针设置当前对象的value值
    }

    int getValue() {
        return this->value; // 使用this指针获取当前对象的value值
    }
};

int main() {
    MyClass obj1, obj2;

    obj1.setValue(10); // 设置obj1的value值
    obj2.setValue(20); // 设置obj2的value值

    std::cout << "Value of obj1: " << obj1.getValue() << std::endl; // 获取并打印obj1的value值
    std::cout << "Value of obj2: " << obj2.getValue() << std::endl; // 获取并打印obj2的value值

    return 0;
}

        下面给出具体的代码进行分析this指针的使用过程:这个示例展示了在C++中使用this指针解决名称冲突和返回对象本身的情况。在这个示例中,定义了一个名为Person的类,其中包括了一个构造函数和成员函数PersonAddAge,以及一个整型成员变量age。

        解决名称冲突:在函数test01中,创建了一个Person对象p1并初始化其年龄为18,在构造函数中使用了this指针来设置对象的年龄。通过this指针,可以准确地访问当前对象的成员变量,避免与函数参数或局部变量发生冲突。

        返回对象本身:在函数test02中,创建了两个Person对象p1和p2,并多次调用PersonAddAge函数来累加p1对象的年龄到p2对象。在PersonAddAge函数中,使用了this指针来访问当前对象的成员变量,同时返回值类型为Person&,表示返回的是当前对象的引用,实现了对同一个对象连续调用多次函数的链式操作。

        在test02函数中,通过链式调用的方式,三次调用PersonAddAge函数将p1对象的年龄累加到p2对象中,最终输出了p2对象的年龄。

        值得注意的是,在链式调用时需要确保PersonAddAge函数返回的是当前对象的引用(*this),这样才能保证连续调用的有效性。

        通过这个示例,展示了this指针在成员函数中的作用,以及如何使用this指针解决名称冲突和实现返回对象本身的功能。

#include <iostream>
using namespace std;

class Person
{
public:
	Person(int age)
	{
		// this指针指向的是被调用的成员函数所属的对象
		this->age = age;   
	}

	Person& PersonAddAge(Person &p)
	{
		this->age += p.age;
		return *this;   // this指向的是p2的指针,而*this指向的就是p2这个对象本体
	}

	int age;   // 这里一般会定义的时候,尽量与构造函数传入的参数分辨清楚,或者在构造函数里加入this
};

// 1、解决名称冲突
void test01()
{
	Person p1(18);
	cout << "p1的年龄: " << p1.age << endl;

}


// 2、返回对象本身用 return *this 且返回值类型,为该对象的类,加引用方式返回

void test02()
{
	Person p1(10);

	Person p2(10);

//	p2.PersonAddAge(p1);
	// 若想使用链式的方法多次相加,需要进行成员函数更改
	/* 具体方面如下
	   1、当成员函数PersonAddAge()执行一次之后,返回值是void
	   2、返回值是void,当然不能再对该成员函数进行调用,因此,返回值必须是p2才可以
	   3、而这里说了返回对象本身用 return *this 且返回值类型,为该对象的类,加引用方式返回
	   4、因此改成

	   Person &PersonAddAge(Person &p)
	   {
	        this->age += p.age;
			return *this;
	   }
	*/
	p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);


	cout << "p2的年龄为:" <<p2.age<< endl;

}

int main()
{
	//test01();
	test02();

	system("pause");
	return 0;
}

        示例运行结果如下图所示:

04-空指针访问成员函数                  

        在C++中,空指针访问成员函数是指在一个空指针上调用成员函数的情况。空指针是指未指向任何有效对象的指针,即其存储的地址为0或nullptr。当尝试在空指针上调用成员函数时,由于没有有效对象来执行函数,可能会导致程序崩溃或未定义的行为。

        空指针的含义

        空指针是指未指向任何有效对象的指针,通常表示为nullptr(在C++11及以后版本)或0(在较早的C++版本中)。

        空指针不指向任何有效的内存地址,因此在其上调用成员函数将导致未定义的行为。

        空指针访问成员函数的影响

        当在空指针上调用成员函数时,由于没有有效的对象来执行函数体,程序可能会发生崩溃或产生未定义的行为。

        这是因为成员函数通常需要访问对象的成员变量或其他成员函数,而空指针并不指向任何对象,因此无法执行成员函数的操作。

        下面是一个简单的示例,演示了空指针访问成员函数的情况:

        在这个示例中,创建了一个名为MyClass的类,其中包含一个成员函数printMessage用于打印消息。在main函数中,创建了一个空指针ptr,并尝试在其上调用printMessage成员函数。

        然而,由于ptr是一个空指针,它并不指向任何有效的对象,因此在调用printMessage函数时将导致未定义的行为,可能会导致程序崩溃或产生其他意外结果。

#include <iostream>

class MyClass {
public:
    void printMessage() {
        std::cout << "Hello, world!" << std::endl;
    }
};

int main() {
    MyClass* ptr = nullptr; // 创建一个空指针

    ptr->printMessage(); // 尝试在空指针上调用成员函数

    return 0;
}

        解决方法:

        为了避免空指针访问成员函数导致的问题,可以在调用成员函数之前进行空指针的有效性检查,确保指针不为空才进行调用。例如:通过这样的有效性检查,可以避免空指针访问成员函数带来的潜在问题,增加程序的健壮性和稳定性。

if (ptr != nullptr) {
    ptr->printMessage();
} else {
    // 处理空指针的情况,如输出错误信息或进行其他操作
    std::cerr << "Error: Pointer is null." << std::endl;
}

下面给出具体代吗分析应用:

#include <iostream>
using namespace std;

// 空指针调用成员函数

class Person
{
public:
	
	void showClassName()
	{
		cout << "this is Person class" << endl;
	}
	void showPersonAge()
	{
		// 这里传入的指针为空,将会报错
		if (this == NULL)   // 这个判断可以防止传入空指针出错
		{
			return;
		}
		cout << "年龄age = " << m_Age << endl;
	}
	int m_Age;
};

void test01()
{
	Person *p = NULL;
	p->showClassName();

	// 这里出错,主要原因如下
	/* 1、cout << "年龄age = " << m_Age << endl;这句代码里m_Age这里默认是this->m_Age
	   2、但是这里定义的对象只是一个空指针,对于一个空指针来说,访问里面的成员是不可能的
	*/
	p->showPersonAge();

}



int main()
{
	test01();
	//test02();

	system("pause");
	return 0;
}

         示例运行结果如下图所示:

总结                  

        在C++中,对象模型和this指针是面向对象编程的两个重要概念,它们有助于理解类和对象之间的关系以及在类的成员函数中操作对象的方式。

        在C++中,对象模型是用来描述类和对象之间关系的一种模型。在C++中,每个对象都有自己的一组成员变量和方法,这些成员变量和方法定义在类中。当创建一个对象时,该对象会占用一些内存空间来存储其成员变量,并且会有一个指向类的指针,这个指针指向该对象所属的类。

        this指针是一个隐含的指针,它指向当前对象的地址。在类的成员函数中,可以使用this指针来访问当前对象的成员变量和方法。this指针的类型是指向当前类的指针。

 

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

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

相关文章

文心一言 VS 讯飞星火 VS chatgpt (255)-- 算法导论18.3 1题

一、请说明依次从图18-8(f)中删除C、P和V后的结果。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 首先&#xff0c;让我们明确一点&#xff1a;由于您没有提供具体的图18-8(f)的内容&#xff0c;我只能假设它是一个数据结构&#xff08;可能是图、树或列表等&…

【spring】Security 密码加密算法

Spring Security 提供了多种密码加密算法&#xff0c;用于在存储用户密码时进行加密&#xff0c;以增强安全性。 查看org.springframework.security.crypto.factory.PasswordEncoderFactories 以下是一些常用的密码加密算法&#xff1a; BCryptPasswordEncoder&#xff1a; 这…

白酒:酒精度数与白酒品质消费的关联性研究

酒精度数作为白酒的一项重要指标&#xff0c;不仅影响着白酒的口感和风格&#xff0c;更在很大程度上与白酒的消费存在密切关联。在探讨云仓酒庄豪迈白酒时&#xff0c;我们不能忽视酒精度数与品质消费之间的关联性。 首先&#xff0c;酒精度数的高低直接影响到白酒中酒精的含量…

企业活动想联系媒体报道宣传如何联系媒体?

在企业的宣传推广工作中,我曾经历过一段费事费力、效率极低的时期。那时,每当公司有重要活动或新项目需要媒体报道时,我便要一家家地联系媒体,发送邮件、打电话,甚至亲自登门拜访,只为求得一篇报道。然而,这样的过程充满了不确定性和挑战,时常让我感到焦虑和压力山大。 记得有一…

gif压缩大小但不改变画质怎么做?分享5个压缩GIF原理~

GIF&#xff08;图形互换格式&#xff09;是网络上广泛使用的一种图像格式&#xff0c;因其支持动画而备受欢迎。然而&#xff0c;随着动画越来越复杂和高分辨率&#xff0c;GIF 文件大小也随之增加&#xff0c;可能导致加载速度变慢和带宽消耗增加。在这篇文章中&#xff0c;我…

编程怎么学?踏上编程之旅:如何高效学习编程

编程怎么学&#xff1f;踏上编程之旅&#xff1a;如何高效学习编程 编程&#xff0c;作为数字时代的核心技能&#xff0c;正吸引着越来越多的人投身其中。然而&#xff0c;面对浩瀚的知识体系和纷繁的学习资源&#xff0c;初学者往往感到迷茫。本文将为你指引一条高效的编程学习…

pyqt动画效果放大与缩小

pyqt动画效果放大与缩小 QPropertyAnimation介绍放大与缩小效果代码 QPropertyAnimation介绍 QPropertyAnimation 是 PyQt中的一个类&#xff0c;它用于对 Qt 对象的属性进行动画处理。通过使用 QPropertyAnimation&#xff0c;你可以平滑地改变一个对象的属性值&#xff0c;例…

[每周一更]-(第96期):Rsync 用法教程:高效同步文件与目录

文章目录 一、引言二、rsync 基本概念三、介绍rsync 是什么&#xff1f;四、安装五、rsync 基本语法常见示例&#xff08;默认ssh协议&#xff09;&#xff1a; 六、常用选项1. -a 或 --archive2. -v 或 --verbose3. -z 或 --compress4. --delete5. --exclude6. --exclude-from…

飞腾E2000运行Zephyr操作系统

Phytium-Zephyr-SDK 1. 仓库介绍 1.1 本仓库特色 此项目是一个开源软件&#xff0c;专为物联网领域设计&#xff0c;基于Zephyr实时操作系统&#xff0c;针对Phytium系列CPU进行了专门的适配和应用开发。我们的目标是降低开发者的使用门槛&#xff0c;提供了部署文档和使用指…

【算法入门赛】B. 自助店评分(C++、STL、推荐学习)题解与代码

比赛地址&#xff1a;https://www.starrycoding.com/contest/8 题目描述 在上一场的入门教育赛中&#xff0c;牢 e e e找到了所有自助店的位置&#xff0c;但是他想发现一些“高分好店”&#xff0c;于是他利用爬虫技术从“小众点评APP”中爬取了武汉所有自助店的评分。 评分…

Linux应用(四)——系统IO函数

本节学习linux系统中常见的IO函数&#xff0c;讲解及其基本用法&#xff1b; 一、 open/close函数 open函数作用:系统调用open函数&#xff0c;打开指定路径的文件&#xff1b; int open(const char *pathname, int flags&#xff09;&#xff1b;打开一个存在的文件&#xff1…

【大学物理】东北大学-马文蔚听课笔记

4.1刚体的定轴转动_哔哩哔哩_bilibili 此笔记为课堂学习笔记~ 4.1刚体的定轴转动 基本教学要求 什么时刚体呢&#xff1f; 研究刚体运动切口 平动&#xff1a;刚体中所有的点的运动轨迹都完全相同。 转动&#xff1a;分为&#xffe5;定轴转动和非定轴转动 刚体转动的角速度…

人脸采集训练识别

项目概述&#xff1a; 本地摄像头采集人脸数据集&#xff0c;通过训练得到trainingData.yml模型&#xff0c;加载haarcascade_frontalface_default.xml实现人脸识别。haarcascade_frontalface_default.xml 文件并不是一个完整的人脸识别模型&#xff0c;而是一个用于检测正脸&a…

基于Spring Cloud的房产销售平台设计与实现

基于Spring Cloud的房产销售平台设计与实现 开发语言&#xff1a;Java 框架&#xff1a;SpringCloud JDK版本&#xff1a;JDK1.8 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台首页界面&#xff0c;前台首页包括房源信息、…

RS485空调系统到BACnet江森楼宇系统的高效整合攻略

智慧城市的每一栋建筑都在追求更高的能效与更佳的居住体验&#xff0c;而这一切的实现离不开强大且灵活的楼宇自动化系统。其中&#xff0c;协议转换网关作为连接不同设备的纽带&#xff0c;扮演着至关重要的角色。本文将以一个典型的商业综合体为例&#xff0c;揭秘BACnet协议…

零基础开发新闻小程序带评论点赞收藏功能,可以回复评论,借助小程序云开发云模板开发一款图文小程序,新闻列表新闻详情,登录注册功能

小程序官方有改版了&#xff0c;搞得石头哥不得不紧急的再新出一版&#xff0c;教大家开通最新版的cms网页管理后台 一&#xff0c;技术选型和技术点 1&#xff0c;小程序前端 wxml css JavaScript MINA原生小程序框架 2&#xff0c;数据库 云开发 云数据库 云…

力扣:62. 不同路径

62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

20232906 2023-2024-2 《网络与系统攻防技术》第九次作业

20232906 2023-2024-2 《网络与系统攻防技术》第九次作业 1.实验内容 本次实践的对象是一个名为pwn1的linux可执行文件。 该程序正常执行流程是&#xff1a;main调用foo函数,foo函数会简单回显任何用户输入的字符串。 该程序同时包含另一个代码片段&#xff0c;getShell&am…

【负载均衡式在线OJ项目day4】编译运行功能整合及打包网络服务

一.前言 前面两天完成了编译和运行两个子模块&#xff0c;今天的任务是完成CompileRun模块&#xff0c;它的任务如下&#xff1a; 解析来自客户端的Json字符串&#xff0c;反序列化提取编译运行需要的数据&#xff0c;即代码&#xff0c;时间限制和空间限制把代码写入临时文件…

太阳能无人机的多元化应用

随着新能源技术的不断发展和成熟&#xff0c;太阳能在无人机的应用技术已经成熟。太阳能无人机得到了量产和广泛的应用。传统无人机相比&#xff0c;太阳能无人机无需燃油&#xff0c;运行费用低廉&#xff0c;搭载多种高科技设备&#xff0c;能够高效、多元化地采集和分析各类…