c++拷贝对象时的优化问题

简介: 博主是基于VS2019测试的,不同编译器可能情况不一样。看下面这一个类A:

博主是基于VS2019测试的,不同编译器可能情况不一样。

看下面这一个类A:

class A
{
public:
  A(int a = 0)
    :_a(a)
  {
    cout << "A(int a = 0)" << endl;
  }
  A(const A& aa)
    :_a(aa._a)
  {
    cout << "~A(const A& aa)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
  A& operator= (const A& aa)
  {
    cout<<" A& operatoor = (const A & aa)" <<endl;
    if (this != &aa)
    {
      _a = aa._a;
    }
    return *this;
  }
private:
  int _a;
};
void f1(A aa)
{}
A f2()
{
  A aa;
  return aa;
}

示例分析

只有传值传参

// 传值传参
A aa1;
f1(aa1);
cout << endl;    //一次构造,一次拷贝构造



1376bcaa95b24136a2fd4cac29866dfa.png

直接优化例子:

// 隐式类型,连续构造+拷贝构造->优化为直接构造
f1(1); 


ae543948616e4ff987b8c477d9adc12c.png

// 一个表达式中,连续构造+拷贝构造->优化为一个构造
f1(A(2));    
cout << endl;


1798736116ad4a2cb553ef1c11816ee6.png

传值返回

// 传值返回
f2();    //   1次 构造一次 + 1次 拷贝构造
cout << endl;


e27388935b1746c1aa321010e97abd23.png

按道理说是1次构造+2次拷贝构造,但是编译器在遇到这种连续的拷贝构造,会自动优化成1次拷贝构造。

  // 一个表达式中,连续拷贝构造->优化为一个拷贝构造
  A aa1 = f2();
  cout << endl;



04515557dd044e05b7eaf6c151306771.png


349888fbe884493694ab95713eea082f.png

// 一个表达式中,连续拷贝构造+赋值重载->无法优化
A aa1;
aa1 = f2();
cout << endl;


c1ff5e34f7ea44bb98d1b9d2fe3b6318.png

55f95e059d5849eca72f005aff820ed0.png

一道例题

void f1(A aa)
{}
A f2()
{
  A aa;
  return aa;
}
A f(A u)
{
  A v(u);
  A w = v;
  return w;
}
int main()
{
  A x;
  A y = f(f(x));
}

请问调用了几次构造和拷贝构造?

1次构造和7次拷贝构造


f5f95dcd28544703b7c31c587a219082.png

调用示例如图所示:


1a7d09a7e6bf43068e4189b2d0d78bb0.png 

目录
相关文章
|
1月前
|
编译器 C++
C++之类与对象(完结撒花篇)(上)
C++之类与对象(完结撒花篇)(上)
35 0
|
11天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
40 4
|
12天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
35 4
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
1月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
24 4
|
1月前
|
存储 编译器 C语言
【C++打怪之路Lv3】-- 类和对象(上)
【C++打怪之路Lv3】-- 类和对象(上)
17 0
|
1月前
|
编译器 C++ 数据库管理
C++之类与对象(完结撒花篇)(下)
C++之类与对象(完结撒花篇)(下)
31 0
|
5天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
24 5
|
1月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
21 1
|
1月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)