对象的优化

简介: 对象的优化
class Test {
public:
  Test(int a = 10) : ma(a) {
    cout << this << endl;
    cout << "constructor" << endl;
    //cout << __FUNCTION__ << endl;
  }
  ~Test() {
    cout << this << endl;
    cout << "destructor" << endl;
    //cout << __FUNCTION__ << endl;
  }
  Test(const Test &t) : ma(t.ma) {
    cout << this << endl;
    cout << "copy constructor" << endl;
    //cout << __FUNCTION__ << endl;
  }
  Test& operator=(const Test &t) {
    cout << this << endl;
    cout << "operator constructor" << endl;
    //cout << __FUNCTION__ << endl;
    ma = t.ma;
    return *this;
  }
private:
  int ma;
};
int main() {
  Test t1;
  Test t2(t1);
  Test t3 = t1;
  /*
  c++编译器对于对象构造的优化,用临时对象生成新对象的时候
  临时对象就不产生了,直接构造新对象就可以了
  */
  Test t4 = Test(20);//Test t4(20);//没有区别
  t4 = t2;
  //t4.operator=(const Test &t)
  cout << "=========" << endl;
  //显式生成临时对象
  t4 = Test(30);
  cout << "=========" << endl;
  t4 = (Test)30;  //int -> Test(int)
  //隐式生成临时对象
  t4 = 30;  //int -> Test(int)
  Test *p = &Test(40);
  //p指向一个已经析构的对象
  const Test &ref = Test(50);
  cout << "=====end=====" << endl;
  return 0;
}

程序输出:

0047FB20
constructor
0047FB14
copy constructor
0047FB08
copy constructor
0047FAFC
constructor
0047FAFC
operator constructor
=========
0047FA0C
constructor
0047FAFC
operator constructor
0047FA0C
destructor
=========
0047FA00
constructor
0047FAFC
operator constructor
0047FA00
destructor
0047F9F4
constructor
0047FAFC
operator constructor
0047F9F4
destructor
0047F9E8
constructor
0047F9E8
destructor
0047FAD8
constructor
=====end=====
0047FAD8
destructor
0047FAFC
destructor
0047FB08
destructor
0047FB14
destructor
0047FB20
destructor
class Test {
public:
  //Test() Test(a) Test(a, b)三种构造
  Test(int a = 5, int b = 5) 
    : ma(a)
    , mb(b)
  {
    cout << this << endl;
    cout << "constructor" << endl;
    //cout << __FUNCTION__ << endl;
  }
  ~Test() {
    cout << this << endl;
    cout << "destructor" << endl;
    //cout << __FUNCTION__ << endl;
  }
  Test(const Test &t) : ma(t.ma), mb(t.mb) {
    cout << this << endl;
    cout << "copy constructor" << endl;
    //cout << __FUNCTION__ << endl;
  }
  void operator=(const Test &t) {
    cout << this << endl;
    cout << "operator constructor" << endl;
    //cout << __FUNCTION__ << endl;
    ma = t.ma;
    mb = t.mb;
  }
private:
  int ma;
  int mb;
};
Test t1(10, 10);//1.Test(int, int)
int main() {
  Test t2(20, 20);  //3.Test(int, int)
  Test t3 = t2;   //4.Test(const Test &)
  //static Test t4(30, 30);
  static Test t4 = Test(30, 30); //5.Test(int, int)
  t2 = Test(40, 40);//6.Test(int, int)  operator=   ~Test()
  //逗号表达式强转(50, 50) = (Test)50;
  t2 = (Test)(50, 50);  //7.Test(int, int) operator= ~Test()
  t2 = 60;        //Test(int) 8.Test(int, int) operator= ~Test()
  Test *p1 = new Test(70, 70);  //9.Test(int, int)
  Test *p2 = new Test[2];     //10.Test(int, int) Test(int, int)
  Test *p3 = &Test(80, 80);   //11.Test(int, int) ~Test()
  const Test &p4 = Test(90, 90);  //12.Test(int, int)
  cout << "============" << endl;
  delete p1;            //13.~Test();
  delete[] p2;          //14.~Test() ~Test()
  return 0;
}
Test t5(100, 100);//2.Test(int, int)
00CAF2D8    //t1
constructor
00CAF2E0    //t5
constructor
0096F908
constructor
0096F8F8
copy constructor
00CAF2E8        //t4
constructor
0096F7E8
constructor
0096F908
operator constructor
0096F7E8
destructor
0096F7D8
constructor
0096F908
operator constructor
0096F7D8
destructor
0096F7C8
constructor
0096F908
operator constructor
0096F7C8
destructor
009DF060
constructor
009DE8BC
constructor
009DE8C4
constructor
0096F788
constructor
0096F788
destructor
0096F8B8
constructor
============
009DF060
destructor
009DE8C4
destructor
009DE8BC
destructor
0096F8B8
destructor
0096F8F8
destructor
0096F908
destructor
00CAF2E8          //t4
destructor
00CAF2E0          //t5
destructor
00CAF2D8          //t1
destructor
class Test {
public:
  //Test() Test(a)两种构造
  Test(int a = 5) 
    : ma(a)
  {
    cout << this << endl;
    cout << "constructor" << endl;
  }
  ~Test() {
    cout << this << endl;
    cout << "destructor" << endl;
  }
  Test(const Test &t) : ma(t.ma){
    cout << this << endl;
    cout << "copy constructor" << endl;
  }
  void operator=(const Test &t) {
    cout << this << endl;
    cout << "operator constructor" << endl;
    ma = t.ma;
  }
  int getData() const { return ma; }
private:
  int ma;
};
//不能返回局部的或者临时对象的指针或引用
Test GetObject(Test t)//3.Test(const Test &)
{
  int val = t.getData();
  Test tmp(val);//4.Test(int)
  return tmp;//5.Test(const Test &)返回值临时变量拷贝构造
}
//6.tmp析构
//7.形参析构
int main() {
  Test t1;//1.Test(int)
  Test t2;//2.Test(int)
  t2 = GetObject(t1);
  //8.operator=
  //9.~Test(),返回值临时变量拷贝析构
  //10.t2析构
  //11.t1析构
  return 0;
}

程序输出:

0113F798
constructor
0113F78C
constructor
0113F684
copy constructor
0113F654
constructor
0113F6B4
copy constructor      //返回值的拷贝构造
0113F654
destructor
0113F684
destructor
0113F78C
operator constructor
0113F6B4
destructor        //返回值的析构
0113F78C
destructor
0113F798
destructor

三条对象优化原则

1.函数参数传递过程中,对象优先按引用传递,不要按值传递
2.函数返回对象的时候,应该优先返回一个临时对象,而不要返回一个定义过的对象
//不能返回局部的或者临时对象的指针或引用
Test GetObject(Test &t)//1
{
  int val = t.getData();
  /*Test tmp(val);
  return tmp;*/
  //返回临时对象, 2
  //用临时对象拷贝构造一个新对象时,临时对象不会构造,而是直接构造新对象
  return Test(val);
}
int main() {
  Test t1;
  Test t2;
  t2 = GetObject(t1);
  return 0;
}

程序输出:

00BAF830
constructor
00BAF824
constructor
00BAF758
constructor
00BAF824
operator constructor
00BAF758
destructor
00BAF824
destructor
00BAF830
destructor

如果是这样调用呢:

int main() {
  Test t1;
  Test t2 = GetObject(t1);//3
  //t2 = GetObject(t1);
  return 0;
}

程序输出:

0137FD4C
constructor
0137FD40
constructor
0137FD40
destructor
0137FD4C
destructor

可以看到函数返回值的对象也没有生成而是直接初始化了t2,因此第三条:

3.接收返回值是对象的函数调用的时候,优先按初始化的方式接收,不要按赋值的方式接收
相关文章
|
14天前
new 一个对象的过程中发生了什么
new 一个对象的过程中发生了什么
|
10月前
|
JavaScript 前端开发
如何把一个对象变成可迭代对象?
如何把一个对象变成可迭代对象?
|
1月前
|
存储 Java
JVM整体结构解析
JVM整体结构解析
|
7月前
|
安全 编译器 程序员
25 C++ - 动态对象创建
25 C++ - 动态对象创建
31 0
|
10月前
|
安全 编译器 C++
【C++】影响动态多态的静态联编与对象切割
在使用C++动态多态时,有时候会出错误,这里讲述其中的两个原因
42 0
【C++】影响动态多态的静态联编与对象切割
优化对象变高效
没有优化过的对象,不足以看出C++的优势
玩转JVM中的对象及引用:从创建到引用到分配和优化策略
类加载检查 当Java虚拟机遇到一条new指令的时候,它会先去运行时常量池中寻找new的类的符号引用,并且检查这个符号引用所代表的类是否已经被加载、解析、初始化过。如果没有即需要进行相应的类加载过程。
|
JavaScript 前端开发 索引
带你手写一个对象,深入理解可迭代对象是什么,与类数组有什么区别
带你手写一个对象,深入理解可迭代对象是什么,与类数组有什么区别
148 0
带你手写一个对象,深入理解可迭代对象是什么,与类数组有什么区别
|
缓存 Oracle IDE
深入分析Java反射(八)-优化反射调用性能
Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行Debug。
326 0