首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我不能直接在临时对象上调用operator()?

在C++中,临时对象是指在表达式中创建的且没有被命名的对象。operator()是一个函数调用运算符,它允许对象像函数一样被调用。

然而,不能直接在临时对象上调用operator()的原因是,临时对象的生命周期是由编译器自动管理的,它们在表达式结束后会立即被销毁。因此,如果在临时对象上调用operator(),那么在调用完成后,临时对象就会被销毁,而无法再访问它的成员或使用它的返回值。

为了解决这个问题,可以使用以下两种方法之一:

  1. 将临时对象赋值给一个命名对象,然后在该对象上调用operator()。这样可以确保对象的生命周期足够长,以便在调用完成后继续使用它。
  2. 使用lambda表达式来替代临时对象的调用。lambda表达式可以在创建时捕获临时对象,并在需要时调用operator()。

总结起来,不能直接在临时对象上调用operator()是因为临时对象的生命周期短暂,无法保证在调用完成后继续使用它。需要将临时对象赋值给一个命名对象或使用lambda表达式来解决这个问题。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++编程经验(8):对象优化,试试?试试就逝世哈哈哈

显示生成临时对象,生存周期为所在的语句 test t4 = test(20); //调用的是test(int) //这里本应该是先初始化一个临时对象,再讲临时对象拷贝给t4, //但事实是直接为t4...,再使用复制构造函数将临时对象复制到t4 //离开了这条语句之后,临时对象的生命周期结束,调用析构 ------------------ operator = test() operator = ~...return &temp; } 这里是不能这么写的,因为 temp(val) 是一个栈内临时对象,在函数结束的时候就会被析构的,如果编译不过就算了,我的VS编译过了,于是卡死了,果然没有让我失望哈。...---- 案例六: 一波微调 test GetObject(test t) { //不能返回局部或临时对象的指针或引用 int val = t.getdata(); test temp(val)...operator = //将main函数栈帧上的临时对象赋值给t2 ~test() //析构该临时对象 ***********************************************

28030

C++:Vector的模拟实现

思考:为什么迭代器也要搞个类模板呢?         答:本质上是为了让这个函数更加灵活,可以传不同类型的迭代器来帮助我们初始化!!...2.const T&val=T()  T()不是用一次就析构吗,为什么可以用引用 答:T()是一个用一次就析构的匿名对象,其实本质上是因为他没有名字,用T引用val可以充当他的名字,此时用val就相当于用这个匿名对象...3.非法的间接寻址是为什么? 如下图我传(10,5),会出非法间接寻址  但是我传(10u,5)就可以正常使用了,为什么会这样??..._end_of_storage); }         拷贝构造的现代写法思路:创建一个临时对象利用被拷贝对象的迭代器区间构造,然后再swap一下就可以了!...swap(temp);//窃取革命成果 }        赋值重载的现代写法的思路:反正我自己的空间也不要了,被赋值对象传值过来(这样被赋值对象不会被修改),然后直接和临时对象swap就可以了!

10610
  • 【C++入门篇】保姆级教程篇【下】

    如果想实现这个操作,我们有必要在实现一个operator+的运算符重载,首先,我们需要保证返回的日期类是不会影响调用者的对象的,其实我们只需要在原有的operator+=的函数内部创建一个临时对象,对本对象进行拷贝...Date operator+(int day) { Date tmp(*this);//创建临时对象对本对象进行拷贝 //用临时对象实现+=操作,这样就不会对本类对象进行改变了 tmp....我们上面的例子也算是解释了第1个问题,const对象不能调用非const成员函数,因为权限不能被放大调用,只能平移或者缩小。...现在我想实现一个类,来计算调用这个类会创建了多少个对象。...,我们为什么不能再类中声明的时候给个缺省值?

    14610

    临时变量作为非const的引用进行参数传递引发的编译错误

    ---- 2.所有的临时对象都是const对象吗 为什么临时对象作为引用参数传递时,必须是常量引用呢?很多人对此的解释是临时对象是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。...这个解释在关于理解临时对象不能作为非const引用参数这个问题上是可以的,但不够准确。...事实上,临时变量是可以被作为左值(LValue) 并被赋值的,请看下面的代码: class IntClass{ private: int x; public: IntClass(int...operator<< ostream& operator<<( ostream &os, const IntClass &intc) { os<<intc.x; return os; }...这里贴上摘自网上的一句话:“内置类型产生的临时变量具有常性,而自定义类型产生的临时变量不具有常性”,我想这句话能解释你所谓的临时变量为什么能作为左值的原因。”

    2.6K31

    【c++】类和对象(七)

    n,那么如果我想要使同一个n++呢?...绑定到常量引用 在很多编程语言中,通常不能直接将一个临时对象(或字面量)赋值给一个引用。然而,C++允许一个临时对象绑定到一个常量引用上。这里的const A& aa2 = 2;正是这样的情况。...因此,没有拷贝构造函数被调用,因为我们没有创建一个新的A对象,只是创建了一个临时对象的引用 没有拷贝构造的调用 在这个过程中,临时对象是直接在需要的位置构造的,然后aa2被绑定到这个对象上。...由于aa2是一个引用,它实际上并不拥有对象;它只是一个到临时对象的链接。...因此,不需要调用拷贝构造函数来创建一个新的A对象,这个机制避免了不必要的拷贝,提高了效率 常量引用延长临时对象的生命周期 在C++中,将临时对象绑定到常量引用上的一个重要后果是,这个临时对象的生命周期会被延长

    8920

    手搓string类

    ,临时变量tmp在出这个函数就要被销毁,调用析构的时候delete一个野指针就会产生错误。..._size; return *this; } } 现代写法,使用传值传参,然后直接使用临时变量交换,这个写法是我比较推荐的(太简洁了) void swap(string&s) { std::..._capacity); } string& operator=(string s) { swap(s);//传值传参,s是一个拷贝,直接使用这个临时变量,反正临时变量出了这个函数就被销毁了 return...*this; } s是一个拷贝的临时变量,在销毁的时候会自动调用析构函数清理,不用我们做额外处理,而且直接使用临时变量调用swap还省去了我们创建临时变量。...为了减少扩容次数,我可以建立一个数组,这个数组满了就往s中插入,数组满一次才扩容一次,有效减少扩容次数 stream& operator>>(istream& in, string& s)//要对s插入数据

    33400

    C++运算符重载详解(日期类实操)

    1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this+1 //       而temp是临时对象,因此只能以值的方式返回,不能返回引用 Date Date::operator...,编译器自动传递  // 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this+1(调用拷贝构造函数)  //       而temp是临时对象...,因此只能以值的方式返回,不能返回引用 this指向的对象函数结束后不会销毁,故以引用方式返回提高效率 输入流输出流操作符重载 为什么cin cout能够自动识别任意类型的数据呢?...如果我们使用值传送来传递一个流给函数,那么在函数里要生成一个该流的临时变量,生成临时变量的时候,就要调用对应的拷贝构造函数,并且这个拷贝构造函数必须是以一个值传送的流作为参数的——但是流就是没有这样的拷贝构造函数...成员函数定义的规则: 能定义成const的成员函数都应该定义成const,这样const对象(权限平移)和非const对象(权限缩小)都可以调用 要修改成员变量的成员函数,不能定义成const 注意本质修饰的是成员函数

    6910

    C++之类和对象

    而面向对象的语言在遇到问题时则不再将重点放在过程上,而是将重点转移到解决这个问题需要的对象上。...那么为什么要有封装?封装本质上是一种管理,它可以让用户更方便使用。...,但可以修改其指向的对象 (我们可以通过 this 指针修改成员变量的值,但不能让 this 指向其他对象) 3.this 指针本质上是“成员函数”的一个形参,当对象调用成员函数时,将对象地址作为实参传递给...可以看到,这里我定义了一个const类型的只读日期类,甚至连打印都做不到,这是为什么?...,所以每个成员都只能在初始化列表中出现一次: 就像世界上很多事只有第一次才让人充满感触一样,要牢记初始化只能有一次 2.如果我显示写了初始化列表,那么编译器就会调用我显示写的;否则对于内置类型编译器会使用随机值来初始化

    1.2K00

    C++ 运算符重载的基本概念

    — 1 — 运算符重载的需求 C++ 预定义的运算符,只能用于基本数据类型的运算:整型、实型、字符型、逻辑型等等,且不能用于对象的运算。...如:c = a + b; 等价于c = operator+(a,b) 在上面的代码中,我把重载+号运算符的普通函数,在Complex复数类中定义成了友元函数,目的是为了友元函数能访问对象的私有成员,否则会编译报错...// 重载-号运算符,属于成员函数 Complex Complex::operator-(const Complex & c) { // 返回一个临时对象 return Complex(m_real -...,就会调用默认的赋值(拷贝)构造函数,产生了一个临时对象,这会增大开销,所以就采用引用的方式,同时又为了防止引用的对象被修改,所以就定义成了const Complex & c常引用类型。...再来说一下返回值为什么是普通Complex对象,因为本次 - 号和 + 号运算符的函数执行之后,需要返回一个新的对象给到左值。

    1K40

    适合具备 C 语言基础的 C++ 入门教程(十三)

    如果在main函数中的i的最大值是是一个很大的数,那么程序就会调用很多次test_func函数,但是由于test_func函数里没有delete操作,那么这个时候由new获得的内存就会一直不能得到释放,...(); sp tmp(p); ==> sp(Person *p) /*tmp 表示的是临时变量*/ sp other(tmp); ==> sp(sp &other2) 那为什么会报错呢?...这是因为第三条语句,我们将第三条语句进行以下剖析,第三条语句实际上是相当于下面这条语句: sp &other2 = tmp; 那这条语句是为什么会出错呢,这是因为tmp当前是一个临时变量,而临时变量是不能够赋值给非常量引用的...,那么如果我想要用sp定义任何类型的对象呢,这个时候,就需要使用到模板的概念,下面是改进后的sp类的模板函数的代码: template class sp { private:...->() { return p; } T& operator*() { return *p; } } 实际上也很简单,只是将之前的Person换成了T。

    35600

    【C++】————类和对象(下)

    +(int day) { Date ret(*this); ret += day;//这里直接调用上面这个函数就可以了 return ret; } 可以发现日期加天数就是创建一个临时的对象用来储存传过来的对象...Date* const this,也就是说明这里的this指向的对象不能改变,但是本身的值可以改变,但是如果我们传一个const对象,就是指向的对象和值都不能改变,那样会咋变呢,如果直接传,就会出现权限的放大问题...写法就是:然后后面每一句前面几上,即可。不要去在乎这样写的原因是啥,主要还是要记住就是这样去写。...静态成员变量:属于整个类而不是某个具体对象,所有该类的对象共享这一个静态成员变量。 静态成员函数:可以通过类名直接调用,不依赖于具体对象,不能访问非静态成员变量(但可以通过对象访问)。...为什么呢? 原因就是使用A()去返回的时候还返回啥临时对象啊,直接在接受返回值的地方构造就可以了,一个表达式,多次构造 +拷贝构造的 都会被优化为1次构造,这就是编译器的优化。

    9210

    C++拾趣——有趣的操作符重载

    其实不用担心,因为smp也是Sample对象,且这个重载是Sample类的成员函数,所以在语法上是合法的。  ...如果我只重载前置,那么使用者只能在使用前置操作符时才能产生正确的行为,但是使用者不知道后置是不能使用的。这种不对等的行为也是违反“隐性共识”的。所以这个问题的答案是“否”。...第9行是后置实现,它在自增前使用了拷贝构造函数构造了一个和当前对象保存一样信息的临时对象,然后自增当前对象,最后返回了临时对象。        ...这样编译器会将2隐式构造成一个Sample临时对象(调用Sample(int n)构造函数)。        ...因为它用于支持标准输出,于是操作符左侧值是std::ostream对象,这样它就不能声明为成员函数了。

    79830

    【C++11】右值引用和移动语义

    那这种情况我们之前说过,由于tmp这个局部对象函数调用结束就销毁了,所以这里会产生一个临时对象(是tmp的拷贝)作为返回值。...),所以这里会产生一个临时对象,这个临时对象是一个将亡值,所以它会去移动构造valStr。...首先第一个移动拷贝就是我们上面分析的,返回值str被识别成了右值,直接移动构造临时变量,然后临时变量赋值给了s1 为什么后面打印两次深拷贝? 因为我们的赋值重载里面复用了拷贝构造。...bit::to_string函数中会先用str生成构造生成一个临时对象,但是我们可以看到,编译器很聪明的在这里把str识别成了右值,调用了移动构造。...然后再把这个临时对象做为bit::to_string函数调用的返回值赋值给ret1,这里调用的移动赋值。 C++11给STL中的容器都增加了移动构造和移动赋值。

    18010

    【C++】踏上C++学习之旅(八):深入“类和对象“世界,掌握编程的黄金法则(三)(内含运算符重载和拷贝构造函数)

    至于为什么,我后面会讲的,这里埋一个伏笔。 1.3 拷贝构造函数的"特性" 拷贝构造函数是构造函数的一种重载形式。...函数调用过程中将实参值传递给形参的过程中最能体现这一观点,这也就是为什么我们经常说"值传递时,形参是实参的一份临时拷贝"!。 对于自定义类型的值拷贝来说,编译器会去调用对应的拷贝构造函数!...目的是杜绝编译器出现关于自定义类型无穷递归调用的问题。 这里还要解决一个问题就是,我不加const限定符可以吗? 答案是建议加上。为什么呢?...函数原型:返回值类型 operator操作符(参数列表) 注意: 不能通过连接其他符号来创建新的操作符:比如operator@ 重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如...this保存 //一份,然后给this + 1 //而temp是临时对象,因此只能以值的方式返回,不能返回引用 Date operator++(int) { Date temp(*this); _day

    7900

    优化对象变高效

    << "------------" << endl; t4 = t2; // t4.operator = (const Test & t); // 显式生成临时对象 /* 因为这时候...int->Test(int) cout << "------------" << endl; return 0; } 运行结果为: t4 = Test(30);是先临时生成一个对象所以调用了...Test(int),这个临时对象再赋值给t4,所以调用了operator=,临时对象再析构,所以是~Test() 下面这三行代码,都是 Test(int) operator= ~Test() // 显式生成临时对象...,所以就算tmp传递一个指针,我们通过返回值知道地址后,但是这个函数运行结束后,这个内存就没了,所以这个对象的内存也就没了,那你知道了他的地址也没用了,所以不能返回局部的或者临时对象的指针或者引用 */...11个函数 三条对象优化的规则 1.函数参数传递过程中,对象优先按引用传递,不要按值传递 2.函数返回对象的过程中,应该优先返回一个临时对象,而不要返回一个定义过的对象 3.接收返回值是对象的函数调用的时候

    8710

    适合具备 C 语言基础的 C++ 教程(十三)

    如果在main函数中的i的最大值是是一个很大的数,那么程序就会调用很多次test_func函数,但是由于test_func函数里没有delete操作,那么这个时候由new获得的内存就会一直不能得到释放,...这是因为第三条语句,我们将第三条语句进行以下剖析,第三条语句实际上是相当于下面这条语句: sp &other2 = tmp; 那这条语句是为什么会出错呢,这是因为tmp当前是一个临时变量,而临时变量是不能够赋值给非常量引用的...临时变量没有名字,自然不能够赋值给非常量引用 而解决方法,也很简单,那就改成常量引用就好了,因此,我们将拷贝构造函数改为如下的形式: class sp { private: Person *p;...image-20210228210842670 对照着代码,我们可以看到Person对象被指向的次数,而且在更改之后的基础上运行,代码就没有出现错误了。...,那么如果我想要用sp定义任何类型的对象呢,这个时候,就需要使用到模板的概念,下面是改进后的sp类的模板函数的代码: template class sp { private:

    45210

    什么是 lvalue, rvalue, xvalue

    但不包括 string literals (例如 "hello" 实际上是一个 lvalue,其类型是 const char *) 实质上的函数调用:(return non-reference) f()...也就是为一个本来不实际存在于内存中的对象(prvalue), 悄悄建立了一个匿名的、临时的、在内存中有地址的对象(xvalue)。...实际上,这里问题发生在 operator M*(),它看似没有参数,实质上它的参数是 this,且概念上形式为 M().this (1),符合 Temporary Materialization 的条件...T a = T(); 构造函数 T::T() 只被调用了一次,等号右边的 prvalue T() 根本没有存在过(或者理解成 T() 是直接在 a 的地址上构造出来的),没存在过显然也就没有地址。...*pf, p->*pf, 其中 f 和 pf 都是普通成员函数(non-static),则它们都是 prvalue,这个我暂时还不理解为什么这样设计。

    5.9K72

    【编程基础】前置++和后置++详解

    前置++: type operator++(); 后置++: const type operator++(int ); 为了编译器区分前置和后置++,C++规定后缀形式有一个int类型参数 ,当函数被调用时...{ CInt old = * this ; ++ ( * this ); return old; } 上面的实现解释了一个关键问题:前置比后置效率高 ,后置需要构造临时对象并返回...那为什么前置和后置返回参数不同呢?...前置仅仅是对自身进行运算,并将自身返回,这样外面可以直接对这个返回对象再进行操作 ,如 (++it)->function() 后置因其返回的不是原来的对象,此时再进行额外操作,改变的是临时对象的状态,...那为什么不返回const &呢?因为不能这么做,返回引用将无效,临时对象已经不存在了。 所以后置返回const 对象即限制对此临时对象进行误操作,并显式地告诉调用者此对象仅为原对象的副本。

    1.1K60

    【C++修炼之路】27.右值引用

    之前提到过,在调用函数之后会销毁函数栈帧,会生成一个临时对象拷贝函数返回值,这个临时变量之所以有常性就是因为其是右值。 函数返回值就是右值!...,我发现三条都是在第二行赋值时调用的,当我f11进入时,首先进入了to_string函数,直到调试到return str,我知道这里会再次调用移动构造,因此我再次按住f11,不出所料,跳到了移动构造string...(string&& s)里,接下来就是一直按住f10,当返回到main中的原语句时,我再次按住f11,结果不出所料,他进入到了赋值重载string& operator=(const string& s)...中,此时就是调用了深拷贝,打印两个深拷贝的原因实际上是因为有一个tmp的构造,而第一次的深拷贝实际上不是深拷贝,只是进入的一个标志,即实际上只进行了一次深拷贝。...,我们明明已经加上移动构造和移动拷贝了,为什么仍然调用深拷贝?

    27400
    领券