【C++】匿名对象超详细详解(什么是匿名对象?对象可以是哪些类型呢?)

目录

一、前言

 二、匿名对象的概念详解

🥝 语法结构

🍍概念理解 

三、匿名对象的对象类型

 四、匿名对象的使用

🍇简单场景的使用 

 🍉复杂场景的使用

五、总结

六、共勉


一、前言

        在C++中,匿名对象(Anonymous Object)是指在没有被命名的情况下创建的临时对象。它们通常用于在单个语句中执行一系列操作或调用某个函数,并且不需要将其结果存储到变量中。

      匿名对象的创建非常简单,只需在类名后面使用一对空括号。接下去呢我们来谈一谈C++中的匿名对象,可能你在C语言结构体章节中听说过【匿名结构体】,但是【匿名对象】你有听说过吗?

 二、匿名对象的概念详解

🥝 语法结构

 【语法格式】类名()

🍍概念理解 

class A {
public:
	A(int a)
	{
		cout << "A构造函数的调用" << endl;
		_a = a;
	}

	~A()
	{
		cout << "A析构函数的调用" << endl;
	}
private:
	int _a;
};
  • 首先看到这里有一个类A,然后在下面实例化了两个类A的对象,分别使用的是【有名对象】【匿名对象】,此时就可以很明显地看出它们的区别之所在,匿名对象很明显就是没有名字
int main(void)
{
	A a1(10);	// 有名对象 -- 生命周期在当前函数局部域
	A(20);		// 匿名对象 -- 生命周期在当前行
	return 0;
}

👉对于【有名对象】而言,其生命周期在当前函数局部域

👉对于【匿名对象】而言,其生命周期在当前行

  • 这一块我们可以通过调试来进行观察,可以发现对于匿名对象执行完当前的这一行就直接去调用析构了,所以它的生命周期之后一行(其实不一定,看下去你就知道了)

 那知道了其特性后我们便可以去用一用这个匿名对象呢

三、匿名对象的对象类型

 匿名对象不仅可以是类类型,也可以是内置类型,比如 int、double 等等

  • 首先我们来看一下内置类型的匿名对象 
int main()
{
	cout << int() << endl;        // 0
	cout << double() << endl;    // 0
	return 0;
}
  •  可以看出,内置类型的匿名对象都是 0

接下来,我们将 类类型 和 内置类型混合使用,来看看 

template<typename T>
void Print(int n , const T& val = T())
{
	for (int i = 0; i < n; i++)
	{
		cout << val << " ";
	}
	cout << endl;
}

int main()
{
	cout << int() << endl;         // 0
	cout << double() << endl;      // 0
	Print<int>(5);           // 0 0 0 0 0
	Print<string>(5);        // 空
	return 0;
}

 四、匿名对象的使用

🍇简单场景的使用 

下面有一个类,现在我们要去调用这个类中的成员函数,你会如何去进行调用呢? 

class Solution {
public:
	int Sum_Solution(int n) 
	{
		cout << "Sum_Solution" << endl;
		return n;
	}
};
  • 相信最常规的做法就是像下面这样,实例化出一个对象,然后通过对象.函数名()的形式进行调用
Solution s;
s.Sum_Solution(1);
  • 但是呢,我直接使用下面这一种形式也可以做到,即【匿名对象】去进行调用,虽然这一种调用形式比较方便,但是呢是存在局限性的,我们只能调用这么一次,若是你想要多次调用类中的这个函数时,就需要去构造【有名对象】了,其生命周期是到程序结束为止的
Solution().Sum_Solution(2);

 🍉复杂场景的使用

 💬 请问下面这匿名对象可以被引用吗,快速回忆一下C++引用的相关知识

A& ra = A(1);
  • 编译一下可以发现是做不到的,如果你【C++引用】这一块学习扎实的话,相信很快就能想到是 权限放大 的问题,那这里为什么会造成权限放大呢?原因就在于这个匿名对象它和临时对象一样是具有常性的,那一个非常性的对象去引用常性的就会有问题了

  • 此时我们只需要在前面加上一个const即可
const A& ra = A(1);

💬 那我现在还想问题,这一块也是涉及引用相关的知识,因为这个匿名对象的生命周期只在这一行,那么此时这个ra是否会变成【野引用】呢?即引用了一块已经不存在的空间? 

  •   其实就是因为这个const常引用的原因,延长了匿名对象的生命周期,那么前面的对象ra是正常的对象,对这个匿名对象进行了引用即取了别名,那么就会在程序结束的时候才进行销毁

接下去我们再来看第二块,有关STL中的string 

  • 看到我这里是写了一个函数,形参部分是一个string的常引用
void push_back(const string &s)
{
	cout << s << endl;
}

然后我在下面写了调用这个函数的三种形式

  • 第一种是实例化对象然后去进行调用
  • 第二种采用的就是我们上面所学习的【匿名对象】
  • 第三种是直接传递了一个【常量字符串】进去,这中间会产生一个【临时对象】,然后进行隐式类型转换
  • 那你会更喜欢哪种方式呢,不用猜,一定是这第三种方式
// 1
string str("11111");
push_back(str);
// 2
push_back(string("22222"));
// 3
push_back("33333");
  •  对于第二种的【匿名对象】和第三种的【临时对象】,它们都具有一个常属性,所以在函数的形参部分不可以是普通的引用,不然就会产生一个权限放大的问题,加上const后就是权限平移,此时既可以接受普通引用也可以接收常引用,提高了代码的健壮性 

五、总结

1️⃣:匿名对象的生命周期非常短暂,只在当前语句中有效。一旦执行到语句结束,匿名对象就会被销毁。因此,无法在后续的代码中再次引用该对象。
2️⃣:匿名对象的对象可以为:类类型,也可以是内置类型

3️⃣:匿名对象也可以有自己的构造函数、析构函数和成员函数,它们的行为与具名对象一样。但由于匿名对象没有名称,所以无法直接访问它们。

六、共勉

   以下就是我对 C++ 匿名对象 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 C++STL库 的理解,请持续关注我哦!!!     

  • 31
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值