- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
以下面的类为例
#include <iostream>
using namespace std;
class A{
private:
int a_;
int b_;
A(const A&) = delete;
A& operator=(const A&) = delete;
A(A&&) = delete;
A& operator=(A&&) = delete;
public:
A(int a, int b) : a_{a}, b_{b}{cout<<"constructed\n";}
void ephemeral() const{cout<<"operation\n";}
~A(){cout<<"destructed\n";}
};
A make_A(int a, int b){
return {a, b};
}
int main(){
make_A(1, 2).ephemeral();
return 0;
}
It gives the expected result .
构造对象,执行操作,然后销毁。
但是,我担心这是否得到保证。我主要担心的是,由于标准赋予编译器的自由,我是否会看到我不知道的任何效果。
我不认为复制省略是这里的一个因素,因为所有移动和复制构造函数都被声明为已删除,所以如何调用它们?
唯一被调用的构造函数是接受两个整数的构造函数。我能确定这将在编译器、平台和优化级别上保持一致吗?
我怀疑答案是"is",但可能会有一些微妙之处。
最佳答案
当你return {a,b};
你直接构造返回值。
没有创建临时的、逻辑的或其他的。没有省略。
此返回值在 main
的返回上下文中可用.你可以调用它的.ephemeral()
手术。在完整表达式的末尾,它超出范围,除非您将它“存储”在 A const&
中。 (引用生命周期延长开始)或 A&&
(同上)或在 auto const&
中或 auto&&
像这样的变量:
auto&& a = make_A(1, 2);
a.ephemeral();
仍然,在上述情况下,没有发生复制。
这些操作都不会导致标准下的复制。
在某些情况下,您是正确的,复制构造可以被删除。省略是指两个对象的身份和生命周期合并。所以如果make_A
阅读:
A make_A(int a, int b){
A r{a,b};
return r;
}
r
可以省略到返回值中。然而,在这里,编译器会要求 A(A const&)
或 A(A&&)
被定义,所以它不会用你的 A
编译.实际上,一旦检查到它们已定义,它就不会调用它们,因为 r
在 make_A
内将被忽略为与 make_A
的返回值相同的对象.
同样,
A a = make_A(1,2);
make_A
返回的临时文件省略为与命名变量相同 a
.省略是暂时的,所以这也可以一起省略变量within make_A
.在这种情况下,您还需要 A(A&&)
或 A(A const&)
存在。
通过删除移动/复制构造器,它们无法被调用,因此对象无法被复制。每个构造函数只能调用一个析构函数(除非手动构造或销毁)。
如果代码尝试调用它们,将在编译时产生错误。
在 C++17 中你甚至可以 return A(a,b);
并发生类似的保证。
您也可以A a = make_A(1,2);
并发生类似的保证。
这被描述为“保证省略”,而是将一些操作变成了“如何构造某些东西的描述”。
因此,在某些情况下,您可以在 C++03 或 C++11 或 C++14 中执行需要移动或复制 ctors 的操作,但在 C++17 中现在执行类似于“elision”的操作"并且不再需要移动或复制 ctors。
关于c++ - 当返回一个用花括号初始化列表初始化的对象时,我能保证一对构造函数和析构函数调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39880720/
我是一名优秀的程序员,十分优秀!