将可变数量的args传递给类中的另一个方法

时间:2012-03-25 20:28:14

标签: c++ class variadic-functions

我有以下(简化目的)代码,它可以工作:

void log(const string type, const string msg, va_list argp)
{
    fprintf(stdout, "[%s] ", type.c_str());
    vfprintf(stdout, msg.c_str(), argp);
}

void log_err(const string msg, ...)
{
    va_list argp;

    va_start(argp, msg);
    log("ERROR", msg, argp);
    va_end(argp);
}

我会以这种方式使用它:

log_err("test: %d", 5);

但是,如果我想把它移到课堂上:

class Logger {
public:
    Logger() {
        //
    };
    void generic(const string type, const string msg, va_list argp) {
        fprintf(stdout, "[%s] ", type.c_str());
        vfprintf(stdout, msg.c_str(), argp);
    };
    void error(const string msg, ...) {
        va_list argp;

        va_start(argp, msg);
        this->generic("ERROR", msg, argp);
        va_end(argp);
    };
};

然后我得到了分段错误。我知道像va宏这样棘手的东西无法在类范围内工作,但我想知道原因。

感谢您的建议!

修改

使用示例:

Logger logger;
logger.error("test", 5);

完整来源:

#include <string>
#include <cstdlib>
#include <cstdarg>

using namespace std;

void log(const string type, const string msg, va_list argp)
{
    fprintf(stdout, "[%s] ", type.c_str());
    vfprintf(stdout, msg.c_str(), argp);
}

void log_err(const string msg, ...)
{
    va_list argp;

    va_start(argp, msg);
    log("ERROR", msg, argp);
    va_end(argp);
}

class Logger {
    public:
        Logger() {
            //
        };
        void generic(const string type, const string msg, va_list argp) {
            fprintf(stdout, "[%s] ", type.c_str());
            vfprintf(stdout, msg.c_str(), argp);
        };
        void error(const string msg, ...) {
            va_list argp;

            va_start(argp, msg);
            this->generic("ERROR", msg, argp);
            va_end(argp);
        };
};

int main()
{
    //log_err("test: %s\n", "str");

    Logger logger;
    logger.error("test %s", 5);

    return 0;
}

我不想让这些方法保持静态,因为在原始使用中我有私有文件描述符,我正在写日志消息;

2 个答案:

答案 0 :(得分:3)

错误就在这一行:

      logger.error("test %s", 5);

%s格式说明符用于C样式字符串。 5不是C风格的字符串。使用:

      logger.error("test %s", "5");

或:

      logger.error("test %d", 5);

答案 1 :(得分:0)

你有99%的路在那里。变化

 void generic(const string type, const string msg, va_list argp)

void generic(const string type, const string msg, va_list & argp)

似乎你无法复制列表(没有参考就完成了)

编辑::我上面发布的内容是错误的。第一次通过我只是假设提供了seg故障,没有参考就没有测试。我删除了参考,所有打印都很好。

留给未来的人们。