簡體   English   中英

成員函數中的臨時對象-C ++

[英]Temporaries in member functions - C++

將一些代碼投入工作后,我正在嘗試對其進行優化。 我要避免的一件事是創建臨時對象。 上一堂課

class foo{
   private:
     int a;
   public:
     foo(int sa):a(sa);
     ~foo(){}
    inline int multiply(int b) {return a*b;}//temporary?
};

英特爾編譯器給了我這里使用的臨時創建/引用臨時文件。 是否正在創建任何臨時變量?

編輯:編輯了返回類型。 另外,我認為沒有乘法會創建臨時變量,但是intel編譯器給我一個錯誤。

編輯2:在以下請求之后,這是intel編譯器v.12給出錯誤的完整代碼:

 #include <iostream>
 #include <complex>

 using namespace std;
 const double pi = 3.1415;
 const complex <double> I = (0.0,I);
 const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));

  class foo{
     private:
       complex <double> a;
     public:
       foo(complex <double> sa):a(sa){}
       ~foo(){}
       inline complex <double> multiply(complex<double> b) 
       {return  a*sqrt(b);}
   };

編譯行是

  icc -g -O2 -w2 -debug parallel -Wcheck -Weffc++ -mp -fp-stack-check -wd981 -wd2015 -wd1418  test.cpp -o  test

結果警告是

  test.cpp(7): remark #383: value copied to temporary, reference to temporary used
  const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));
                                         ^

問題是要了解編譯器在做什么,而不是太討厭。

謝謝!

不用擔心

您正在做的事情被稱為“過早的微觀優化”,這是許多邪惡根源

嘗試進行微優化在很大程度上也是徒勞的

  1. 無需先對代碼進行性能分析並確定需要優化的位置,就可以進行微優化,這完全是在浪費時間。 可能最終將一個耗時數百萬皮秒的例程減少了皮秒。 何必呢?

  2. 編譯器將大大優化您的代碼。 例如,MicroSoft擁有一群人,他們的唯一工作就是在優化器上工作。 他們是非常聰明的人,每天整天都在努力尋找優化代碼的方法。 在這種情況下,臨時人員通常會被優化掉。 讓他們做自己的事。 他們比你更好。

  3. 微觀優化通常以難以理解的代碼為代價。 難以理解的代碼更容易出現缺陷。 如果您的函數返回“ fA @#zzzzzzzzz”而不是“ foo”,則保存的這4皮秒毫無價值。

首先,為您的任務選擇正確的算法。 然后編寫實現這些算法的良好,健壯的代碼。 概要文件處於釋放模式。 在分析器的指導下,找到確實需要優化的位置(如果有的話)。 然后優化。

這並不能真正回答您的問題(我不確定自己在哪里創建臨時變量),但是總的來說,創建臨時原始變量不會節省任何速度,因為唯一的區別是所使用的堆棧空間-因此是否除非有頁面錯誤(這種可能性很小),否則堆棧指針將增加4字節或8字節與程序的速度無關。 因此,您不太可能看到類似這樣的性能提升,特別是如果編譯器通過將變量放入寄存器來優化代碼時。

我認為編譯器會發出警告,因為它會翻譯:

const complex <double> oneover2piI = (1.0 / (2.0 * pi * I));

調用默認的復制構造函數:

Object::complex<double>(const complex<double>&)

它以對臨時對象的引用作為參數,並對該對象進行淺表復制(如果使用指針,則將導致數據共享)。 基本上,這種數據共享+臨時壽命是問題的核心。 看看下面的“學術”課程。

#include<iostream>

class A
{

public:

  A()
    :attribute(new char[10]) {}

  ~A()
  {
    std::cout << "d'ctor" << std::endl; 
    if(attribute){
      delete [] attribute;
      attribute = 0;
    }
  }

  A& operator +(const char& n)
  {
    //do some operation
    return *this;
  }

  void reset_attribute(char *new_ptr)
  {
    attribute = new_ptr;
  }

private:

  char *attribute;
};

int main()
{
  {//new scope to invoke destructors
    A b;
    A c = b;
    b.reset_attribute(new char[10]);
  }//no problem in this scope

  A a = (A()+2);//problem with a temporary object

  return 0;
}

cygwin的輸出:

$ ./a.exe
d'ctor //this is from b or c
d'ctor //this is from b or c
d'ctor //this is from temporary
d'ctor //this is from a
Aborted (core dumped)

delete操作已在同一指針上執行了兩次,因為它在臨時對象和a之間共享。

a*b創建一個新的臨時文件。 無論問題文本的其余部分到底意味着什么,我都不知道,但是就您使用“臨時”一詞而言,就創建了一個。

給定您聲稱的代碼,編譯器在抱怨...編譯器不應在抱怨。 既然您還沒有包含真正的錯誤...我絕對不知道為什么您認為它在抱怨您所聲稱的抱怨。

編輯:

假設您聲稱編輯中的代碼是導致您最后引用的錯誤的REAL代碼,那么我敢打賭,編譯器已經被抱怨的那一行完全弄糊塗了:

const complex <double> I = (0.0,I);

我不知道您打算這樣做,但是對我來說這並不合法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM