【问题标题】:Execution of code in a function after the return statement has been accessed in c++在c ++中访问return语句后在函数中执行代码
【发布时间】:2012-02-04 11:57:16
【问题描述】:

我有以下功能:

Class Image {

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

        return img;

        ...
    }
}

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

createImage 函数执行后,我想知道是否有办法在访问 return 语句并填充 newimg 后执行一些代码img 变量的内容。

上面的代码是我想要实现的一个例子。我的主要问题是:有什么方法可以在函数中执行代码,即使在达到 return 语句之后?

【问题讨论】:

  • Erm.. 你为什么不把return 放在最后呢?我的意思是,很明显控制离开函数到达返回语句时...
  • 除了goto,没有。你为什么想做这个?把逻辑分解成多个函数,这才是正确的做法。
  • 您尝试这样做的目标是什么?即使这是可能的,那也是非常违反直觉的,并且可能有更好的方法。

标签: c++ c function opencv return


【解决方案1】:

C/C++ 中任何函数/方法的(无条件)return 语句之后的每一位 auf 代码都是无法访问的代码,永远不会被访问/运行!

【讨论】:

  • int main() { if(0) { return 1; } printf("Reachable code.\n"); return 0; } 可能不同意。短语“C/C++ 中任何函数/方法的 return 语句”本质上具有误导性。
【解决方案2】:

不! 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() 应该很简单,并且按照宣传的方式执行:创建图像。

【讨论】:

  • 它看起来很简单,但即使在返回语句已经到达并且函数不再存在之后,img 是一个指针并且仍然在内存中(我是不太确定这是否正确,但我猜这会造成内存泄漏)
  • @Nicolas 啊,我知道这是怎么回事,这个问题是 OpenCV 特有的。好的,我们开始:cvLoadImage() 将图像加载到 HEAP 内存而不是堆栈中。这就是函数返回后仍然分配内存的原因。释放此函数分配的资源的唯一方法是通过cvReleaseImage()。这是正常行为。放手吧。
【解决方案3】:

要回答这个问题,不,在 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.
}

【讨论】:

  • +1。从技术上讲,这并不能正确回答问题(它规定代码在“在 [...] newimg 已经填充了 img 变量的内容之后”执行),但它已经尽可能接近了。跨度>
  • 这是一种非常好的思维方式。但是,假设我想释放 img 指针怎么办?我还能在 g 的析构函数中做到吗?
【解决方案4】:

是的,您可以创建一个本地对象,该对象将在其析构函数期间执行代码。这是一个例子:

class X
{
    X(){}

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

int a_function()
{
    X x;

    int a = some_calculation();
    return a;
}

这种技术例如与作用域指针一起使用。

【讨论】:

  • 并且请记住,如果需要对其执行操作,对象的构造函数可以引用对局部变量的引用 - 只要它在返回时也没有被销毁。
【解决方案5】:

这是你应该做的。

Class Image {

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

【讨论】:

  • 是的,这不是我想要的。我要问的是我是否可以在 createImage 函数中包含任何代码,即使在实现 return 语句之后也可以执行,并且能够访问在该函数中创建的变量。
【解决方案6】:

这并不难;只返回一个代理对象(而不是一个指针) 它在其析构函数中执行代码。因为你期待一个指针 作为回报,代理对象也应该隐式转换为指针。

话虽如此,但是:您为什么要这样做?你想做什么 在您拨打电话的那一刻之间,createImage 无法做到这一点 cvLoadImage 和你回来的那一刻?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2021-01-16
    相关资源
    最近更新 更多