【问题标题】:IF Statement has strange behaviorIF 语句有奇怪的行为
【发布时间】:2010-06-18 15:35:22
【问题描述】:

我开发了一个“自定义”cout,这样我就可以将文本显示到控制台并将其打印到日志文件中。这个 cout 类在初始化时传递了一个不同的整数,该整数表示消息的详细级别。如果当前详细级别大于或等于消息的详细级别,则应打印该消息。

问题是,即使当前的详细级别太低,我也会打印消息。我继续调试它,期望找到问题。相反,我发现我的 if 语句没有按预期工作的多种情况。

if(ilralevel_passed http://twitpic.com/1xtx4g/full。注意 ilralevel_set 如何等于 0,而 ilralevel_passed 等于 1。然而,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_ */

【问题讨论】:

    标签: c++ debugging if-statement


    【解决方案1】:

    当您在类外部定义静态变量时,您正在为包含标头的每个源文件定义一个单独的变量——更改其中的值不会影响同名变量的值在另一个文件中。

    你几乎肯定想要拥有

    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; }
        // ...
    };
    

    【讨论】:

    • 在类中移动整数将使我的静态函数无法使用它们。由于我不创建对象并直接调用类中的函数,因此这是一个要求。如果我要创建一个对象,我需要不断地为每个单独的对象创建它。
    • @BSchlinker:如果你不创建一个对象,你为什么要使用一个类呢?对于这样的情况,您可能应该在命名空间中只包含函数(和变量)。
    • 我尽量避免使用全局变量(这是我所知道的在两个独立函数之间存储变量的唯一方法)。我对命名空间的使用也不是很熟悉。见:stackoverflow.com/questions/3035582/…
    • @BSchlinker:假设变量只能从您的函数访问/由您的函数访问,您根本不需要在标题中声明它们。只需在实现中定义它们,在标头中声明它们,就可以了。现在出现了问题,因为您在类定义中定义它们,所以它们是内联函数,它将在本地访问变量。刚刚在标头中声明的普通函数将访问定义它们的变量。
    • @Jerry:我目前正在类定义中定义它们?它们虽然在类括号的范围之外——在主头文件本身内。这不是“在标题中声明它们”吗?
    【解决方案2】:

    你不应该像这样在头文件中定义静态变量:

    static int ilralevel_set = 0;
    static int ilralevel_passed;
    

    我不知道你认为这些定义有什么作用,但它们可能没有达到你想要的效果。

    在类中声明:

    struct A {
       static int ilralevel;
    };
    

    然后你需要在一个.cpp源文件中定义:

    int A::ilralevel = 0;
    

    【讨论】:

    • 我还能如何将它们定义为静态变量?您不能在类中定义它们(这实际上是 SO 上的另一个答案,导致我在头文件中定义它们)
    • @BSchlinker 我不太明白你在用它们做什么,但你当然可以在课堂上定义它们。
    • @Neil - 不,你不能。您可以声明它们。在积分的情况下,您可以初始化它们。你不能定义它们;不在类声明中。
    • @Noah 你是对的。我已经更新了我的答案 - 无法更新评论。我相信这将解决所有 OP 的问题。
    • @Noah 什么不正确?如果您不喜欢我的回答,请发布您自己的回答或编辑我的回答。
    【解决方案3】:

    只是一个猜测..您在不同的编译单元中获得了静态全局变量的不同副本。 fx,route.cpp 拥有自己的 ilralevel_passedilralevel_set 副本,以及 irla::operator&lt;&lt; 的内联副本。将ilralevel_passed 移动到irla 的成员变量,将ilralevel_set 移动到static const,看看是否有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多