Если заявление имеет странное поведение - PullRequest
1 голос
/ 18 июня 2010

Я разработал «настраиваемый» cout, чтобы я мог выводить текст на консоль, а также распечатывать его в файл журнала. Этому классу cout передается другое целое число при инициализации, причем целое число представляет уровень детализации сообщения. Если текущий уровень детализации больше или равен уровню детализации сообщения, сообщение должно быть напечатано.

Проблема в том, что у меня печатаются сообщения, даже если текущий уровень детализации слишком низок. Я пошел дальше и отладил его, ожидая найти проблему. Вместо этого я нашел несколько сценариев, в которых мои операторы if работают не так, как ожидалось.

Оператор if (ilralevel_passed <= ilralevel_set) иногда будет продолжаться, даже если ilralevel_set меньше, чем ilralevel_passed. Вы можете увидеть это поведение на следующем рисунке (мои извинения за использование Twitpic) <a href="http://twitpic.com/1xtx4g/full" rel="nofollow noreferrer">http://twitpic.com/1xtx4g/full. Обратите внимание, что ilralevel_set равно нулю, а ilralevel_passed равно единице. Тем не менее, оператор if возвратил true и теперь движется вперед, чтобы передать строку cout.

Я никогда не видел такого поведения раньше, и я не совсем уверен, как продолжить его отладку. Я также не могу изолировать поведение - это происходит только в определенных частях моей программы. Любые предложения приветствуются как всегда.

//  Here is an example use of the function:
//  ilra_status << setfill('0') << setw(2) << dispatchtime.tm_sec << endl;
//  ilra_warning << "Dispatch time (seconds): " << mktime(&dispatchtime) << endl;

//  Here is the 'custom' cout function:
    #ifndef ILRA_H_
    #define ILRA_H_

    // System libraries
    #include <iostream>
    #include <ostream>
    #include <sstream>
    #include <iomanip>

    // Definitions
    #define ilra_talk ilra(__FUNCTION__,0)
    #define ilra_update ilra(__FUNCTION__,0)
    #define ilra_error ilra(__FUNCTION__,1)
    #define ilra_warning ilra(__FUNCTION__,2)
    #define ilra_status ilra(__FUNCTION__,3)

    // Statics
    static int ilralevel_set = 0;
    static int ilralevel_passed;

    // Classes
    class ilra
    {
    public:
        // constructor / destructor
        ilra(const std::string &funcName, int toset)
        {
            ilralevel_passed = toset;
        }
        ~ilra(){};

        // enable / disable irla functions
        static void ilra_verbose_level(int toset){
            ilralevel_set = toset;
        }

        // output
        template <class T>
        ilra &operator<<(const T &v)
        {
            if(ilralevel_passed <= ilralevel_set)
                std::cout << v;
            return *this;
        }

        ilra &operator<<(std::ostream&(*f)(std::ostream&))
        {
            if(ilralevel_passed <= ilralevel_set)
                std::cout << *f;
            return *this;
        }

    };  // end of the class

    #endif /* ILRA_H_ */

Ответы [ 3 ]

6 голосов
/ 18 июня 2010

Когда вы определяете статическую переменную вне класса, вы определяете отдельную переменную для каждого исходного файла, в который вы включаете заголовок - изменение значения в одном не влияет на значение переменной с тем же именем в другом файле.

То, что вы почти наверняка хотите, это иметь

int ilralevel_set = 0;
int ilralevel_passed;

В одном файле, в котором вы определяете свой объект, и:

extern int ilralevel_set;
extern int ilralevel_passed;

в шапке. Кроме того, похоже, что вы можете переместить все это внутри класса:

class ilra { 
    int passed_level;
    int set_level;
public:
    ilra(int toset) : passed_level(toset), set_level(0) {}

    verbose_level(int toset) { set_level = toset; }
    // ...
};
5 голосов
/ 18 июня 2010

Вы не должны определять статические переменные в заголовочном файле следующим образом:

static int ilralevel_set = 0;
static int ilralevel_passed;

Я не знаю, что вы думаете, эти определения делают, но они, вероятно, не делают то, что вы хотите.

Чтобы объявить в классе:

struct A {
   static int ilralevel;
};

Вам необходимо определить в один .cpp исходный файл:

int A::ilralevel = 0;
1 голос
/ 18 июня 2010

Просто предположение ... вы получаете разные копии ваших статических глобалов в разных единицах компиляции. fx, route.cpp имеет собственную копию ilralevel_passed и ilralevel_set, а также встроенную копию irla::operator<<. Переместите ilralevel_passed в переменную-член irla и ilralevel_set в static const и посмотрите, поможет ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...