2012-01-06 22 views
-2

被訪問,我有以下功能:當被執行的createImage功能執行已在C++

Class Image { 

    IplImage* createImage(char* name) 
    { 
     IplImage* img = cvLoadImage(name); 

     return img; 

     ... 
    } 
} 

int main() { 
    IplImage* newimg = createImage("somepath"); 
    return 0; 
} 

後,我想知道是否有辦法在返回語句被訪問並且變量已經填充了變量的內容之後執行一些代碼。

上面的代碼是我想要實現的一個例子。我的主要問題是:有什麼方法可以在函數中執行代碼,即使在返回語句達到之後?

+2

Erm ..你爲什麼不把'return'放在最後?我的意思是,很明顯,當控制*到達返回語句時,它將離開函數... – Xeo 2012-01-06 19:18:14

+0

除了'goto',沒有。你爲什麼想做這個?將邏輯分解成多個功能,這是正確的方法。 – Chad 2012-01-06 19:18:24

+3

試圖做到這一點的目標是什麼?即使這是可能的,那也是非常直觀的,並且可能有更好的方法。 – Nate 2012-01-06 19:18:57

回答

5

不!return指令確實如此,它立即返回。不管什麼事情都不會被執行。

所以,如果有什麼事情想這個功能做的,你必須添加這些任務的代碼功能return前:

IplImage* createImage(char* name) 
{ 
    IplImage* img = cvLoadImage(name); 

    // test if image was loaded and/or 
    // do whatever else you feel you need to do 
    // before: 

    return img; 
} 

記住,你的函數createImage()應該是簡單的,並執行如做廣告:創建一個圖像。

+0

它看起來很簡單,但即使在返回語句達到並且函數不再存在之後,** img **仍然是一個指針並且仍然在內存中(我不太確定這是否正確,但我是猜測會造成內存泄漏) – 2012-01-06 19:43:01

+1

@Nicolas啊,我明白了這是怎麼回事,這個問題是針對OpenCV的。好的,我們開始吧:'cvLoadImage()'將圖像加載到HEAP內存中,而不是堆棧中。這就是爲什麼在函數返回後還有內存分配的原因。釋放這個函數分配的資源的唯一方法是通過'cvReleaseImage()'。這是正常的行爲。隨它吧。 – karlphillip 2012-01-06 22:42:13

1

C/C++中任何函數/方法的(無條件)return語句之後的每一位auf代碼都是無法訪問的代碼,並且永遠不會被訪問/運行!

+0

'int main(){if(0){return 1; } printf(「可達到的代碼。\ n」);返回0; }'可能會不同意。「** C/C++中任何函數/方法的return語句」這個短語具有內在的誤導性。 – ruakh 2012-01-06 19:22:17

1

要回答這個問題,在newimg已經初始化之後(至少不是在createImage函數中),不可能執行代碼。這是最接近你可以得到:

struct post_return_guard{ 
    ~post_return_guard(){ 
    // whatever you want HERE 
    } 
}; 

IplImage* createImage(std::string const& name){ 
    post_return_guard g; 
    IplImage* img = cvLoadImage(name.c_str()); 
    return img; 
    // destructor of 'g' called, code executed. 
} 
+0

+1。從技術上講,這並沒有正確回答這個問題(它規定在newimg已經填充了img變量的內容之後執行代碼),但是它儘可能地接近你所能得到的。 – ruakh 2012-01-06 19:24:34

+0

@ruakh:哦,我誤讀'newimg'爲'img'。編輯。 – Xeo 2012-01-06 19:26:15

+0

這是一個非常好的思維方式。但是如果我們說,我想釋放** img **指針呢?我仍然可以在g的析構函數中做到這一點嗎? – 2012-01-06 19:34:29

3

是的,你可以創建一個本地對象,將在其析構函數執行代碼。這裏是一個例子:

class X 
{ 
    X(){} 

    ~X() 
    { 
     std::cout << "hello" << std::endl; 
    } 
}; 

int a_function() 
{ 
    X x; 

    int a = some_calculation(); 
    return a; 
} 

這種技術是例如與範圍指針一起使用。

+0

請記住,如果需要採取行動,則該對象的構造函數可以引用局部變量 - 只要它在返回時也不會被銷燬。 – 2012-01-06 22:55:08

1

這就是你應該做的。

Class Image { 

    IplImage* createImage(char* name) 
    { 
     IplImage* img = cvLoadImage(name); 
     return img; 
    } 
} 
void doMoreStuff(){ 
     ... 
} 
int main() { 
    IplImage* newimg = createImage("somepath"); 
    doMoreStuff(); 
    return 0; 
} 
+0

是的,這不完全是我所要求的。我所要求的是,在createImage **函數中是否可以有任何代碼,即使在返回語句已經實現之後也可以執行,並且能夠訪問在該函數中創建的變量。 – 2012-01-06 19:38:55

0

這並不困難;只是返回代理對象(而不是指針) 它在其析構函數中執行代碼。由於您期待返回指針 ,因此代理對象也應隱式轉換爲指針。

話雖如此,但你爲什麼呢?你想做什麼 哪一個不能在createImage之間完成,在你撥打 cvLoadImage那一刻和你回來的那一刻之間?