真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++命名返回值優(yōu)化(NRVO)

命名的返回值優(yōu)化(NRVO),這優(yōu)化了冗余拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù)調(diào)用,從而提高了總體性能。值得注意的是,這可能導(dǎo)致優(yōu)化和非優(yōu)化程序之間的不同行為。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計(jì)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了東阿免費(fèi)建站歡迎大家使用!

下面是代碼段1中的一個(gè)簡單示例,以說明優(yōu)化及其實(shí)現(xiàn)方式:

A MyMethod (B &var)
{
    A retVal;
    retVal.member = var.value + bar(var);
    return retVal;
}

使用上述函數(shù)的程序可能具有如下構(gòu)造:

valA = MyMethod(valB);

從MyMethod返回的值是在valA通過使用隱藏的參數(shù)所指向的內(nèi)存空間中創(chuàng)建的。下面是當(dāng)我們公開隱藏的參數(shù)并顯示地顯示構(gòu)造函數(shù)和析構(gòu)函數(shù)時(shí)的功能:

A MyMethod(A &_hiddenArg, B &var)
{
    A retVal;
    retVal.A::A(); //constructor for retVal
    retVal.member = var.value + var(var);
    _hiddenArg.A::A(retVal); // the copy constructor for A
    return;
return.A::~A(); // destructor for retVal
}

上段代碼為不使用NRVO的隱藏參數(shù)代碼(偽代碼)
從上面的代碼可以看出,有一些優(yōu)化的機(jī)會(huì)。其基本思想是消除基于堆棧的臨時(shí)值(retVal)并使用隱藏的參數(shù)。因此,這將消除基于堆棧的值的拷貝構(gòu)造函數(shù)和析構(gòu)函數(shù)。下面是基于NRVO的優(yōu)化代碼:

A MyMethod(A &_hiddenArg, B &var)
{
    _hiddenArg.A::A();
    _hiddenArg.member = var.value + bar(var);
    Resurn
}

帶有NRVO的隱藏參數(shù)代碼(偽代碼)

代碼示例
示例1:簡單示例

#include 

class RVO
{
public:
        RVO() { printf("I am in constructor\n"); }
        RVO( const RVO& c_RVO ) { printf("I am in copy constructor\n"); }
        ~RVO() { printf("I am in destructor\n"); }
        int mem_var;
};

RVO MyMethod(int i)
{
        RVO rvo;
        rvo.mem_var = i;
        return rvo;
}

int main()
{
        RVO rvo;
        rvo = MyMethod(5);
}

代碼:Sample1.cpp
如果沒有NRVO,預(yù)期的輸出將是:

I am in constructor
I am in constructor
I am in copy constructor
I am in destructor
I am in destructor
I am in destructor

使用NRVO,預(yù)期的輸出將是:

I am in constructor
I am in constructor
I am in destructor
I am in destructor

示例2:更復(fù)雜的示例

#include 
class A
{
public:
        A()
        {
                printf("A: I am in constructor\n");
                i = 1;
        }

        ~A()
        {
                printf("A: I am in destructor\n");
                i = 0;
        }

        A(const A& a)
        {
                printf("A: I am in copy constructor\n");
                i = a.i;
        }

        int i, x, w;
};

class B
{
public:
        A a;
        B()
        {
                printf("B: I am in constructor\n");
        }

        ~B()
        {
                printf("B: I am in destructor\n");
        }

        B(const B& b)
        {
                printf("B: I am in copy constructor\n");
        }
};

A MyMethod()
{
        B* b = new B();
        A a = b->a;
        delete b;
        return a;
}

int main()
{
        A a;
        a = MyMethod();
}

代碼Sample2.cpp
無NRVO的輸出將如下所:

A: I am in constructor
A: I am in constructor
B: I am in constructor
A: I am in copy constructor
B: I am in destructor
A: I am in destructor
A: I am in copy constructor
A: I am in destructor
A: I am in destructor
A: I am in destructor

當(dāng)NRVO優(yōu)化啟動(dòng)時(shí),輸出將是:

A: I am in constructor
A: I am in constructor
B: I am in constructor
A: I am in copy constructor
B: I am in destructor
A: I am in destructor
A: I am in destructor
A: I am in destructor

優(yōu)化限制
有些情況下,優(yōu)化不會(huì)真正啟動(dòng)。以下是這些限制的樣本
示例3:異常示例
在遇到異常時(shí),隱藏的參數(shù)必須在它正在替換的臨時(shí)范圍內(nèi)被破壞。

// RVO class is defined above in figure 4
#include 
RVO MyMethod(int i)
{
    RVO rvo;
    cvo.mem_var = i;
    throw "I am throwing an exception!";
    return rvo;
}

int main()
{
    RVO rvo;
    try
    {
        rvo = MyMethod(5);
    }
    catch(char* str)
    {
        printf("I caught the exception\n");
    }

代碼Sample3.cpp
如果沒有NRVO,預(yù)期的輸出將是:

I am in constructor
I am in constructor
I am in destructor
I caught the exception
I am in destructor

如果“拋出”被注釋掉,輸出將是:

I am in constructor
I am in constructor
I am in copy constructor
I am in destructor
I am in destructor
I am in destructor

現(xiàn)在,如果“拋出”被注釋掉,并且NRVO被觸發(fā),輸出將如下所示:

I am in constructor
I am in constructor
I am in destructor
I am in destructor

也就是說sample3.cpp在沒有NRVO的情況下,會(huì)表現(xiàn)出相同的行為。

示例4:不同的命名對象示例
若要使用優(yōu)化,所有退出路徑必須返回同一命名對象。

#include 
class RVO
{
public:
        RVO()
        {
                printf("I am in construct\n");
        }

        RVO(const RVO& c_RVO)
        {
                printf("I am in copy construct\n");
        }

        int mem_var;
};

RVO MyMethod(int i)
{
        RVO rvo;
        rvo.mem_var = i;
        if( rvo.mem_var == 10 )
                return RVO();
        return rvo;
}

int main()
{
        RVO rvo;
        rvo = MyMethod(5);
}

代碼Sample4.cpp
啟用優(yōu)化時(shí)輸出與不啟用任何優(yōu)化相同。NRVO實(shí)際上并不發(fā)生,因?yàn)椴⒎撬蟹祷囟挤祷叵嗤膶ο蟆?/p>

I am in constructor
I am in constructor
I am in copy constructor

如果將上面的示例更改為返回rvo。在返回對象時(shí),優(yōu)化將消除復(fù)制構(gòu)造函數(shù):

#include 
class RVO
{
public:
        RVO()
        {
                printf("I am in constructor\n");
        }

        RVO(const RVO& c_RVO)
        {
                printf("I am in copy constructor\n");
        }

        int mem_var;
};

RVO MyMethod(int i)
{
        RVO rvo;
        if( i == 10 )
                return rvo;
        rvo.mem_var = i;
                return rvo;
}

int main()
{
        RVO rvo;
        rvo = MyMethod(5);
}

代碼Sample4_Modified.cpp修改并使用NRVO,輸出結(jié)果將如下所示:

I am in constructor
I am in constructor

優(yōu)化副作用
程序員應(yīng)該意識(shí)到這種優(yōu)化可能會(huì)影響應(yīng)用程序的流程。下面的示例說明了這種副作用:

#include 

int NumConsCalls = 0;
int NumCpyConsCalls = 0;

class RVO
{
public:
        RVO()
        {
                NumConsCalls ++;
        }

        RVO(const RVO& c_RVO)
        {
                NumCpyConsCalls++;
        }
};

RVO MyMethod()
{
        RVO rvo;
        return rvo;
}

int main()
{
        RVO rvo;
        rvo = MyMethod();
        int Division = NumConsCalls / NumCpyConsCalls;
        printf("Construct calls / Copy constructor calls = %d\n", Division);
}

代碼段Sample5.cpp
編譯未啟用優(yōu)化將產(chǎn)生大多數(shù)用戶所期望的?!皹?gòu)造函數(shù)”被調(diào)用兩次?!翱截悩?gòu)造函數(shù)”被調(diào)用一次。因此除法生成2。

Constructor calls / Copy constructor calls = 2

另一方面,如果上面的代碼通過啟用優(yōu)化進(jìn)行編譯,NRVO將會(huì)啟用。因此“拷貝構(gòu)造函數(shù)”調(diào)用將被刪除。因此,NumCpyConsCalls將為零,導(dǎo)致異常。如果沒有適當(dāng)處理,可以導(dǎo)致應(yīng)用程序崩潰。


引入自:https://msdn.microsoft.com/en-us/library/ms364057(v=vs.80).aspx


網(wǎng)站題目:C++命名返回值優(yōu)化(NRVO)
轉(zhuǎn)載源于:http://weahome.cn/article/jgooee.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部