c ++ #define带括号的宏?

时间:2009-04-17 08:44:25

标签: c++ macros

而不是每次都做以下

start();

// some code here

stop();

我想定义一些宏,它可以写成:

startstop()
{

//code here

}

是否可以在C ++中使用?

9 个答案:

答案 0 :(得分:40)

使用小型C ++帮助程序类可以非常接近。

class StartStopper {
public:
    StartStopper() { start(); }
    ~StartStopper() { stop(); }
};

然后在你的代码中:

{
    StartStopper ss;
    // code here
}

当执行进入块并构造ss变量时,将调用start()函数。当执行离开块时,将自动调用StartStopper析构函数,然后调用stop()

答案 1 :(得分:14)

在C ++中执行此操作的惯用方法称为Resource Acquisition Is Initialization,或称为RAII。除了提供您想要的内容之外,它还具有异常安全的额外好处:即使您的代码抛出异常,也会调用stop函数。

定义一个保护结构:

struct startstop_guard
{
    startstop_guard()
    {
        start();
    }
    ~startstop_guard()
    {
        stop();
    }
};

然后以这种方式重写代码:

{
    startstop_guard g;
    // your code
}

将在封闭块的末尾自动调用guard的析构函数(以及stop函数)。

答案 2 :(得分:6)

其他答案已经很好地解决了问题的RAII方面,所以我将解决它的语法方面

#define startstop for(Starter s; s.loop; s.loop = false)
struct Starter {
    bool loop;
    Starter() { start(); loop = true; }
    ~Starter() { stop(); }
};

一样使用:

startstop {
    // some code
}

应该不言自明。

答案 3 :(得分:4)

#define startstop(x, y, ...) for( /* use macro args */ )

答案 4 :(得分:2)

RAII和boost :: function(std :: function)的通用解决方案。

class starter
{
    typedef boost::function< void () > action;
    action end_;
public:
    starter(action start, action end):
        end_(end)
    { 
        log("starter start");
        start(); 
    }
    ~starter()
    { 
        log("starter end");
        end_() ; 
    }
};
int main()
{
    {
        starter s(start, stop);
        middle();
    }

    return 0;
}

或测试并检查想法

    void print(const std::string& message)
    {
        std::cout << message << std::endl;
    }
    int main()
    {
        starter s(boost::bind(print, "globalstart"),
                  boost::bind(print, "globalend")); 

        {
            starter s(boost::bind(print, "start"),
                      boost::bind(print, "end")); 
            std::cout << "middle" << std::endl;
        }
        return 0;
    }

答案 5 :(得分:1)

你想做什么?我建议将RAII作为一种更多面向C ++的做事方式,而不是宏观黑客攻击,以及所有不可预见的后果。

答案 6 :(得分:1)

不要使用宏。您可以使用内联函数,因为它提供了类型检查和其他功能。你可以看看这里:inline functions

答案 7 :(得分:1)

答案 8 :(得分:0)

在c#中,您可以使用IDisposable模式,并在Dispose()方法中实现Stop()功能,但如果您使用的是c ++的.net变体,那将会有效。