【问题标题】:How can I define a global function to check bounds?如何定义一个全局函数来检查边界?
【发布时间】:2014-08-04 08:49:33
【问题描述】:

我有许多类都使用相同的宽度和高度变量,并且还使用一个函数来检查一个点是否在边界内。比如:

class map
{
    int height;
    int width;

    bool pointExists(int x, int y)
    {
         if(x < 0 || y < 0 || x >width-1 || y>height-1)
            return false;
         return true;
    }
};


class somethingElse
{
int height;
int width;

bool pointExists(int x, int y)
{
    if(x < 0 || y < 0 || x >width-1 || y>height-1)
        return false;
    return true;
}
};

所以...我希望每个班级都可以使用宽度和高度,并且每个班级也可以使用“pointExists”功能。我知道我可以使用全局变量来做到这一点,但我想知道是否有人可以告诉我更好的方法......

【问题讨论】:

  • map 是一个坏名字,因为它与 std::map 冲突
  • widthheightpublic 数据成员吗?
  • 这只是一个例子。我什至不知道代码是否有效。
  • 是的,它们是公开的(我所有程序中的所有内容都是公开的!)
  • 顺便说一句,我认为您的支票更易读的方式是return 0 &lt;= x &amp;&amp; x &lt; width &amp;&amp; 0 &lt;= y &amp;&amp; y &lt; height;

标签: c++ function variables global


【解决方案1】:

使其成为基类和子类

class Element {
protected:
    int height;
    int width;

public:
    bool pointExists(int x, int y)
    {
         return x >= 0 && y >= 0 && x < width && y < height);
    }
};

class map : public class Element {

};

class somethingElse : public class Element {

};

【讨论】:

  • 为什么是一个普通的超类Element,为什么不让somethingElse成为原始map的子类?
  • 不知道要求,是somethingElse "is-a" map?我不知道。
  • somethingelse 可以是任何东西。几乎我所有的课程都需要边界检查。不过,它可能不是网格或地图……更可能与地图非常不同。
  • if (blah) return false; else return true; 让我的眼睛受伤了。为什么不return !blah;
  • @juanchopanza 我同意。已更新。
【解决方案2】:

您可以使用组合来代替继承,例如:

class Dimension
{
    unsigned int height;
    unsigned int width;

    bool pointExists(unsigned int x, unsigned int y) const
    {
        return x < width && y < height;
    }
};

class map { Dimension dim; };
class somethingElse { Dimension dim; };

【讨论】:

    【解决方案3】:

    除了继承示例之外,您还可以将 width, height and pointExists 定义为静态的,因此您不需要对象实例来使用它。我在自己的代码中使用这种方法来创建类似clipping helper 类的东西。所有的访问都是通过静态方法完成的,所以我不需要创建一个实例,它只是将代码和需要的变量包装到一个类中。

    您还可以使用static pointExists(x,y) 代码和静态变量创建一个基类并继承它,这样您就可以为每个类设置不同的height/width 值。

    编辑: 所以这里有一个例子说明它的样子:

    class MyClipper {
        static int width;
        static int height;
    
        public static bool pointExists( int x, int y );
    
        public static void setWidth( int width );
        public static void setHeight( int height );
    };
    
    // somewhere in your scene initialization
    MyClipper::setWidth( 100 );
    
    // another place in your code
    bool b = MyClipper::pointExists( 1, 1 );
    

    【讨论】:

    • 其实这很重要...我想我真的想避免使用实际的对象实例。
    • 这实际上似乎是唯一明智的解决方案。首先,我不必制作任何对象。另外,我不必向每个 bleddy 类传递对象的副本或任何类似的愚蠢行为。而且,我不必继承东西。几乎和全局变量一样有趣!如果可以的话,我会赞成这个答案...
    【解决方案4】:

    你需要定义一个sub-class(使用class继承)

     class somethingElse : public class map {
        // much more things
     };
    

    阅读更多关于 C++ 的资料,尤其是关于它的 rule of three(现在 C++11 中的五规则)

    【讨论】:

      【解决方案5】:

      这正是继承发挥重要作用的问题。

      在继承中,您有一个父类(就像我们有我们的父母一样)和一个子类(就像我和我的兄弟姐妹一样),因此子类可以访问父类中包含的变量和函数以及该变量并且函数不是私有的(就像有些秘密父母甚至不想透露给他们的孩子,所以在编程时秘密是private,而有些秘密是我们的父母告诉我们但不想让我们知道的在编程中向其他人透露秘密是protected,但如果它们是public,你可以告诉任何人。)

      您可以按如下方式完成您的任务:

      1- 创建一个父类(在您的情况下为类 map{...};)并编写您的变量(高度、宽度)和函数(void pointExists(int ,int);)。

      2- 创建子类 (class SomeOtherClass: public map{...};) 并根据您的需要编写一个全局函数,您不需要编写已在父类中编写的相同变量和函数.

      3- 创建 Child 类的对象并通过该对象设置高度和宽度的值,最后调用您的函数(作为 childObject.pointExists(x,y) )。

      【讨论】:

        【解决方案6】:

        声明另一个类点并将变量/函数移动到它。然后在所有需要它的类中继承该点。

        class Area
        {
            int height;
            int width;
        
            bool pointExists(int x, int y)
            {
                 if(x < 0 || y < 0 || x >width-1 || y>height-1)
                    return false;
                 return true;
            }
        };
        
        class map: private Area{
        };
        class somethingElse: private Area{
        };
        

        【讨论】:

        • 方法应该是const,命名不好...AreaDimension似乎比Point更好的名字,对我来说Pointx, y
        【解决方案7】:

        第二种方式是:

        utils.h

        bool in_bounds(int x, int y, int w, int h);
        

        utils.cpp

        #include "utils.h"
        
        bool in_bounds(int x, int y, int w, int h)
        {
            if (x < 0 || y < 0 || x > w - 1 || y > h - 1)
            {
                return false;
            }
            return true;
        }
        

        如果您不想想要使用继承,或者它不能使用,我的方法很好。

        【讨论】:

        • 是的,这种方式意味着我必须每次向函数传递四个变量而不是两个,这有点烦人......
        • “如果你不想想要使用继承,或者它不能使用,我的方法很好” i> 所以在其他情况下使用继承会更好。
        • 对不起,我确实阅读了您的免责声明,只是我最近暂时尝试了这种方法,但它仍然让我感到荨麻疹......
        • C++ 是一种面向对象的语言。如果您不想使用继承,请尝试另一种语言。 (有功能性的 C++ 框架,但我从未尝试过)
        • 你认为,如果在特殊情况下我需要使用过程而不是人为创建的类,我需要选择另一种语言吗?
        猜你喜欢
        • 2019-07-03
        • 2019-04-24
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-15
        • 2011-07-06
        • 1970-01-01
        相关资源
        最近更新 更多