【问题标题】:Is there a standard 'int class' in c++?c++ 中是否有标准的“int 类”?
【发布时间】:2012-03-24 03:22:27
【问题描述】:

是否有(或多或少)用于 c++ 的标准 int 类?

如果不是,是不是计划说C++13,如果不是,有什么特殊原因吗?

我猜,OOP 设计会从中受益,例如,在返回 int 的自定义类中有一个赋值运算符会很好:

int i=myclass;

而不是

int i=myclass.getInt();

好的,有很多有用的例子,为什么不存在(如果不存在)?

它用于航位推算和其他滞后补偿方案,并将这些值视为“正常”变量会很好,希望无论如何!。

【问题讨论】:

  • 没有任何计划,原因是 C++ 不是一种将所有东西硬塞进对象的语言。
  • 如果有这么多例子我想读一些。另外:你想在你的例子中实现什么机制?第一个比第二个更好只是因为它更短吗?我认为第二个比第一个更能将其目的形象化。
  • 普通的int有什么问题?!
  • 您在寻找什么int 没有提供的具体内容?
  • @eda int 变量是一个对象,但 42 不是一个对象。

标签: c++ oop class int


【解决方案1】:

如果你想让你的类隐式转换为int,你可以使用隐式转换运算符(operator int()),但一般来说隐式转换导致的问题和调试比它们在易用性上解决的问题更多。

【讨论】:

  • 显式转换在 C++11 中。
  • 虽然你总是可以用方法来模拟它们。
【解决方案2】:

如果在自定义类中有一个返回 int 的赋值运算符会很好

您可以使用转换运算符来做到这一点:

class myclass {
    int i;
public:
    myclass() : i(42) {}

    // Allows implicit conversion to "int".
    operator int() {return i;}
};

myclass m;
int i = m;

您通常应该避免这种情况,因为额外的隐式转换可能会引入歧义,或者隐藏类型系统会捕获的类别错误。在 C++11 中,可以通过声明运算符 explicit 来防止隐式转换;那么该类可用于初始化目标类型,但不会被隐式转换:

int i(m);    // OK, explicit conversion
i = m;       // Error, implicit conversion

【讨论】:

  • 要使用转换运算符时必须三思而后行,因为它们会使您的代码不那么明显
  • @Alecs:OP 必须至少三次思考他为什么想要这样的语义
  • 我认为我对此行为有一个有效的用例。我想要一个int 的包装类,它通知Java 对象(通过JNI)其值的任何变化。通过使用转换运算符,我能够重载赋值/修改运算符(=++--)来通知 Java 对象,而不会破坏作为 int 对象的现有引用的功能。由于int 是原始数据类型而不是类,因此无法扩展它,这似乎是一个很好的解决方案。我是否遗漏了什么,或者这是解决我问题的好方法?
【解决方案3】:

这可以通过 cast 操作符来实现。例如:

class MyClass {
private:
    int someint;
public:
    operator const int() {
        return this->someint;
    }
}

【讨论】:

    【解决方案4】:

    不,没有任何标准的 int 类。对于 BigDecimal 等内容,您可以查看 Is there a C++ equivalent to Java's BigDecimal?

    至于int,如果真的需要,可以自己创建。我从来没有遇到过需要 Integer 类的实例。

    【讨论】:

      【解决方案5】:

      不,也不会有。你想做的可以用转换运算符来完成:

      #include <iostream>
      
      struct foo {
          int x;
          foo(int x) : x(x) {}
          operator int() { return x; }
      };
      
      int main() {
          foo x(42);
          int y(x);
          std::cout << y;
      }
      

      【讨论】:

      • @sbi:这取决于。如果您正在为受限制的整数范围编写类型,那么隐式转换为 int 正是正确的做法。当然你非常很少这样做。
      • @celtschk:我曾经也这么认为。但我经常被这个咬伤。多年来,我编写的为数不多的隐式转换中的每一个都被删除,这些隐式转换是仍在使用的代码库的一部分,因为它们会造成麻烦。
      • @sbi:那么也许你在inappropriate 隐式转换方面遇到了问题(请注意,我认为C++ 中的许多标准隐式转换都是错误的)。请特别注意,我的示例是一个 restricted int 类,很少有人敢于实现(仅使用 int 就简单得多)。从 extended 整数类(“bigint”)到 int 的隐式转换显然是错误的。
      • @celtschk:如果这些不合适(嗯,IMO 他们肯定是,因为我们不得不删除它们),那么我在编写 C++ 代码的近 20 年中,没有遇到过一个案例隐式转换是适当的。我迟早看到的所有案例都被发现是一些非常难以诊断的错误的罪魁祸首,这些错误是由隐式转换引起的。(顺便说一句,这确实包括Byte 类。)
      • 是从Byteint 的隐式转换(恕我直言)还是从intByte 的转换(恕我直言不合适)结果有问题?
      【解决方案6】:

      不,而且可能不会。

      int i=myclass;
      

      这由转换运算符涵盖:

      struct MyClass {
          operator int() {
              return v;
          }
          int v;
      } myclass = {2};
      int i = myclass; // i = 2
      

      并非一切都必须是“面向对象”的。 C++ 提供了其他选项。

      【讨论】:

        【解决方案7】:

        没有理由拥有一个,所以也不会有。

        【讨论】:

        • 请看我对 Mike Seymour 的评论。
        • 看起来技术上可能(请纠正我)将 C++ 类型系统转换为只有对象。如果我们假装int 是一个最终类,它具有对文字的内置支持的重载运算符。所以 5 创建了一个 int 类的对象。你为什么想这么做?好吧,如果 C++ 还添加了一些方法,例如 repeat,您将能够编写类似 5.repeat([]{ your_code; }); 的东西,不是只有一些向后兼容性问题,例如 type_traits 和 ...?
        • 您现在也可以写repeat(5, []{ your code; });。即使是 C++ 委员会也不够疯狂,无法将 int 变成一个类。 C++ 类型系统已经只由对象(引用除外)组成。没有理由更改已经是对象的现有原语。
        【解决方案8】:

        为你的类实现运算符 int ()

        【讨论】:

          【解决方案9】:

          如果您的班级为int 建模,那么我猜其他答案提供的转换运算符解决方案很好。但是,您的 myclass 模型是什么?

          从中得到一个整数是什么意思

          这就是你应该考虑的问题,然后你应该得出这样的结论,即在没有任何信息的情况下得到一个整数代表什么是很可能毫无意义的。

          std::vector&lt;T&gt;::size() 为例。它返回一个整数。出于这个原因,std::vector&lt;T&gt; 是否应该可以转换为整数?我不这么认为。该方法是否应该称为getInt()?再说一次,我不这么认为。您对名为getInt() 的方法有什么期望?仅从名称中,您就什么了解它返回的什么。此外,它不是唯一返回整数的方法,还有capacity()

          【讨论】:

            【解决方案10】:

            有一个明显的理由来为 int 设置一个类,因为 int 本身不允许缺少任何值。以 JSON 消息为例。它可以包含一个名为“foo”的对象的定义,以及一个名为“bar”的整数,例如:

            {"foo": {"bar": 0}}
            

            这意味着“bar”等于0(零),但是如果省略“bar”,像这样:

            {"foo": {}}
            

            现在有了“bar”不存在的意思,这是完全不同的意思,不能单独用int来表示。在过去,如果出现这种情况,一些程序员会使用单独的标志,或使用特定的整数值来表示该值未提供、未定义或不存在。但是不管你怎么称呼它,一个更好的方法是有一个整数类,它定义了功能并使其可重用和一致。

            另一种情况是数据库表在创建后的某个时间添加了一个整数列。在添加新列之前添加的记录将返回 null,这意味着不存在任何值,并且在创建列之后添加的记录将返回一个值。您可能需要对 null 值与 0(零)采取不同的操作。

            所以这里是 int 或 string 类的开始。但在我们开始编写代码之前,让我们先看看它的用法,因为这就是为什么你首先要创建这个类,从长远来看让你的生活更轻松。

            int main(int argc, char **argv) {
            
                xString name;
                xInt    age;
            
                std::cout<< "before assignment:" << std::endl;
                std::cout<< "name is " << name << std::endl;
                std::cout<< "age is " << age << std::endl;
            
                // some data collection/transfer occurs
                age  = 32;
                name = "john";
            
                // data validation
                if (name.isNull()) {
                    throw std::runtime_error("name was not supplied");
                } 
            
                if (age.isNull()) {
                    throw std::runtime_error("age was not supplied");
                }
            
                // data output
                std::cout<< std::endl;
                std::cout<< "after assignment:" << std::endl;
                std::cout<< "name is " << name << std::endl;
                std::cout<< "age is " << age << std::endl;
            
                return 0;
            }
            

            这是程序的示例输出:

            before assignment:
            name is null
            age is null
            
            after assignment:
            name is john
            age is 32
            

            请注意,当 xInt 类的实例尚未赋值时,

            好的,下面是上面 main 方法的类代码:

            #include <iostream>
            #include <string>
            
            
            class xInt {
            private:
                int  _value=0;
                bool _isNull=true;
            
            public:
                xInt(){}
                xInt(int value) {
                    _value=value; 
                    _isNull=false;
                }
            
                bool isNull(){return _isNull;}
                int  value() {return _value;}
                void unset() {
                    _value=0;
                    _isNull=true;
                }
            
                friend std::ostream& operator<<(std::ostream& os, const xInt& i) {
                    if (i._isNull) {
                        os << "null";
                    } else {
                        os << i._value;
                    }
                    return os;
                }
            
                xInt& operator=(int value) {
                    _value=value;
                    _isNull=false;
                    return *this;
                }
                operator const int() {
                    return _value;
                }
            };
            
            class xString {
            private:
                std::string _value;
                bool   _isNull=true;
            
            public:
                xString(){}
                xString(int value) {
                    _value=value; 
                    _isNull=false;
                }
            
                bool   isNull() {return _isNull;}
                std::string value()  {return _value;}
                void   unset()  {
                    _value.clear();
                    _isNull=true;
                }
            
            
                friend std::ostream& operator<<(std::ostream& os, const xString& str) {
                    if (str._isNull) {
                        os << "null";
                    } else {
                        os << str._value;
                    }
                    return os;
                }
            
                xString& operator<<(std::ostream& os) {
                    os << _value;
                    return *this;
                }
            
                xString& operator=(std::string value) {
                    _value.assign(value);
                    _isNull=false;
                    return *this;
                }
                operator const std::string() {
                    return _value;
                }
            };
            

            有些人可能会说,哇,与只说 int 或 string 相比,这相当难看,是的,我同意它非常罗嗦,但请记住,你只编写一次基类,然后从那时起,你的代码你每天阅读和写作看起来更像我们第一次看到的主要方法,而且非常简洁明了,同意吗?接下来,您将要学习如何构建共享库,以便将所有这些通用类和功能放入可重用的 .dll 或 .so 中,这样您就只编译业务逻辑,而不是整个宇宙。 :)

            【讨论】:

              【解决方案11】:

              你的演员应该意识到这一点

              一个例子

              class MyClass {
              private:
                  int someint;
              public:
                  operator const int() {
                      return this->someint;
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-05-10
                • 2014-04-15
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多