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

简介: 【C++】类和对象(下)(三)

6.拷贝对象时编译器的优化


优化场景1:隐式类型转换==>构造+拷贝构造–>直接构造

class A
{
public:
  A(int a = 10)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
private:
  int _a;
};
int main()
{
  A a1 = 1;
  return 0;
}


这个场景的执行过程是:使用1构造了一个临时变量tmp,再使用这个tmp拷贝构造出a1,但是编译器在执行的时候会只能的优化成直接使用1构造a1。

2b2ce1e21c1277a0a493fb1f4ff8b5cc.png

优化场景2:匿名对象传参==>构造+拷贝构造–>直接构造

class A
{
public:
  A(int a = 10)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
  A(const A& a)
  {
    _a = a._a;
    cout << "A(const A& a)" << endl;
  }
private:
  int _a;
};
void f1(A aa)
{}
int main()
{
  cout << "场景一" << endl;
  A a1(1);
  f1(a1);
  cout << "场景二" << endl;
  f1(A(1));
  return 0;
}


546f14024cc6a9adac613bf57c162b95.png

场景一无法优化,因为两个变量并不能优化成一个,对于场景二,本来是使用1构造一个临时变量,然后传参,拷贝构造出aa,被优化成直接使用1构造aa。


优化场景3:传值返回==>拷贝构造+拷贝构造–>拷贝构造

class A
{
public:
  A(int a = 10)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
  A(const A& a)
  {
    _a = a._a;
    cout << "A(const A& a)" << endl;
  }
private:
  int _a;
};
A f2()
{
  A aa;
  return aa;
}
int main()
{
  A ret = f2();
  return 0;
}

691dacbc9926d30c33966c11ed41a56f.png

在传值返回的时候,会用aa拷贝构造出一个临时变量tmp,然后使用tmp拷贝构造出ret,优化成在调用结束之前使用aa直接拷贝构造出ret。

优化场景4:构造+拷贝构造+拷贝构造–>构造

class A
{
public:
  A(int a = 10)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
  A(const A& a)
  {
    _a = a._a;
    cout << "A(const A& a)" << endl;
  }
private:
  int _a;
};
A f3()
{
  return A(10);
}
int main()
{
  A ret = f3();
  return 0;
}


75e7869e5e9cd4c317ac45e5937c9b82.png

这里触发了一个编译器的极致优化:使用10构造出一个临时变量tmp1,将这个临时变量拷贝构造出一个临时变量tmp2用于传值返回,再使用tmp2拷贝构造ret,最终优化成使用10构造ret。

注意:上述的所有优化都建立在一个步骤中,否则可能会引发一些不必要的风险


个临时变量tmp,然后使用tmp拷贝构造出ret,优化成在调用结束之前使用aa直接拷贝构造出ret。

优化场景4:构造+拷贝构造+拷贝构造–>构造

class A
{
public:
  A(int a = 10)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
  A(const A& a)
  {
    _a = a._a;
    cout << "A(const A& a)" << endl;
  }
private:
  int _a;
};
A f3()
{
  return A(10);
}
int main()
{
  A ret = f3();
  return 0;
}


04dc41397bb7619b031ace44c301c9c6.png

这里触发了一个编译器的极致优化:使用10构造出一个临时变量tmp1,将这个临时变量拷贝构造出一个临时变量tmp2用于传值返回,再使用tmp2拷贝构造ret,最终优化成使用10构造ret。

注意:上述的所有优化都建立在一个步骤中,否则可能会引发一些不必要的风险

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