Передача переменной num аргументов другому методу в классе - PullRequest
0 голосов
/ 26 марта 2012

У меня есть следующий (упрощенный для примера) код, и он работает:

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 ]

3 голосов
/ 26 марта 2012

Ошибка в этой строке:

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

Спецификатор формата %s предназначен для строки в стиле C. 5 не является строкой в ​​стиле C. Использование:

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

или

      logger.error("test %d", 5);
0 голосов
/ 26 марта 2012

Ты на 99% пути.изменить

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

на

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

Кажется, вы не можете скопировать список (что делается без ссылки)

РЕДАКТИРОВАТЬ :: то, что я опубликовал выше,неправильно.При первом прохождении я только предположил, что было предоставлено seg Failed и не проверял без ссылки.Я удалил ссылку, и все напечатано просто отлично.

Оставлено для людей будущего.

...