Assuming that code is located inside if
block, what are differences between creating object in a free store and doing only one call on it:
auto a = aFactory.createA();
int result = a->foo(5);
and making call directly on returned pointer?
int result = aFactory.createA()->foo(5);
Is there any difference in performance? Which way is better?
#include <iostream>
#include <memory>
class A
{
public:
int foo(int a){return a+3;}
};
class AFactory
{
public:
std::unique_ptr<A> createA(){return std::make_unique<A>();}
};
int main()
{
AFactory aFactory;
bool condition = true;
if(condition)
{
auto a = aFactory.createA();
int result = a->foo(5);
}
}
答案 0 :(得分:2)
看here。即使禁用了优化,两个版本的代码也没有区别。
将gcc7.1与-std=c++1z -O0
auto a = aFactory.createA();
int result = a->foo(5);
编译为:
lea rax, [rbp-24]
lea rdx, [rbp-9]
mov rsi, rdx
mov rdi, rax
call AFactory::createA()
lea rax, [rbp-24]
mov rdi, rax
call std::unique_ptr<A, std::default_delete<A> >::operator->() const
mov esi, 5
mov rdi, rax
call A::foo(int)
mov DWORD PTR [rbp-8], eax
lea rax, [rbp-24]
mov rdi, rax
call std::unique_ptr<A, std::default_delete<A> >::~unique_ptr()
和int result = aFactory.createA()->foo(5);
:
lea rax, [rbp-16]
lea rdx, [rbp-17]
mov rsi, rdx
mov rdi, rax
call AFactory::createA()
lea rax, [rbp-16]
mov rdi, rax
call std::unique_ptr<A, std::default_delete<A> >::operator->() const
mov esi, 5
mov rdi, rax
call A::foo(int)
mov DWORD PTR [rbp-8], eax
lea rax, [rbp-16]
mov rdi, rax
call std::unique_ptr<A, std::default_delete<A> >::~unique_ptr()
所以他们几乎完全相同。
当您意识到两个版本之间的唯一区别是在第一个版本中我们将名称分配给对象时,这个结果是可以理解的,而在第二个版本中我们使用未命名的版本。除此之外,它们都是在堆上创建的,并以相同的方式使用。因为变量名对编译器没有任何意义 - 它只对代码阅读器有用 - 它将两者视为相同。
答案 1 :(得分:1)
在您的简单情况下,它不会产生任何影响,因为(主要)功能在创建和使用a
后立即结束。
如果会有更多的代码行,a
对象的销毁将发生在if
的{{1}}块的末尾,而在一行的情况下它会变为在那条单线的尽头被破坏了。但是,如果更复杂的main
的析构函数会对此产生影响,那将是糟糕的设计。
由于编译器优化,应始终通过在具体代码上使用分析器进行测试来回答性能问题。