c ++是否存在(或多或少)标准int类?
如果不是这样,是否计划说C ++ 13,如果不是这样,是否有任何特殊原因?
我认为OOP设计会从中受益,例如,在返回int的自定义类中有一个赋值运算符会很好:
int i=myclass;
而不是
int i=myclass.getInt();
好的,有很多例子可能有用,为什么不存在(如果不存在)?
它适用于航位推算和其他延迟补偿方案,并将这些值视为“正常”变量将是好的,无论如何!希望如此!
答案 0 :(得分:20)
在自定义类中返回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
答案 1 :(得分:5)
如果您希望允许您的类隐式转换为int
,您可以使用隐式转换运算符(operator int()
),但一般来说,隐式转换会导致更多问题和调试,而不是轻松解决使用。
答案 2 :(得分:3)
如果您的班级为int
建模,那么其他答案提供的转换运算符解决方案就可以了。但是,您的myclass
型号是什么?
意味着什么来获取整数?
这就是你应该考虑的问题,然后你应该得出这样的结论:在没有任何信息的情况下得到一个整数很可能毫无意义。
以std::vector<T>::size()
为例。它返回一个整数。出于这个原因,std::vector<T>
是否可以转换为整数?我不这么认为。该方法应该被称为getInt()
吗?我再也不这么认为。您对getInt()
方法的期望是什么?仅从名称中,您就可以了解没有关于它返回的内容。此外,它不是返回整数的唯一方法,也是capacity()
。
答案 3 :(得分:2)
为您的类实现operator int()
答案 4 :(得分:1)
这可以通过 cast 运算符实现。 E.g:
class MyClass {
private:
int someint;
public:
operator const int() {
return this->someint;
}
}
答案 5 :(得分:1)
没有任何标准的int类。对于像BigDecimal这样的东西,你可以查看Is there a C++ equivalent to Java's BigDecimal?
至于int,如果你真的需要它,你可以创建自己的。我从未遇到过需要Integer类的实例。
答案 6 :(得分:1)
不,也没有。您可以使用转换运算符完成您要做的事情:
#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;
}
答案 7 :(得分:1)
不,可能不会。
int i=myclass;
转化运算符涵盖了这一点:
struct MyClass {
operator int() {
return v;
}
int v;
} myclass = {2};
int i = myclass; // i = 2
并非一切都必须是'面向对象'。 C ++提供其他选项。
答案 8 :(得分:1)
有一个明显的理由要有一个int类,因为int本身不允许缺少任何值。以JSON消息为例。它可以包含一个名为“ foo”的对象的定义,以及一个名为“ bar”的整数,例如:
{"foo": {"bar": 0}}
其含义是“ bar”等于0(零),但是如果省略“ bar”,则如下所示:
{"foo": {}}
现在,它具有“ bar”不存在的含义,这是完全不同的含义,不能仅由int表示。在过去,如果出现这种情况,某些程序员将使用单独的标志,或者使用特定的整数值来表示该值未提供,未定义或不存在。但是不管您怎么说,更好的方法是为整数定义一个类,该类定义功能并使其可重用和一致。
另一种情况是数据库表在创建后的一段时间内添加了整数列。在添加新列之前添加的记录将返回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类的实例分配值时,<<操作符会自动打印“ null”而不是零,并且对xString的名称也是如此。您在这里所做的完全取决于您。例如,您可能决定不打印任何内容而不是打印“ null”。另外,为了简洁起见,我对分配进行了硬编码。在现实世界中,您将从文件或客户端连接中收集/解析数据,在该过程中,该过程将根据输入数据中的内容设置(或不设置)数据值。当然,该程序实际上不会抛出运行时异常,但是我将它们放在那里是为了让您更好地了解如何抛出错误。因此,也许有人会说,为什么不在数据收集过程中抛出异常?好吧,答案是,使用扩展的类变量(xInt和xString),我们可以编写一个通用的,可重用的数据收集过程,然后仅检查业务逻辑中返回的数据,然后抛出适当的错误。根据我们的发现。
好的,这是上面的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相比,这很丑陋,是的,我同意这很罗word,但是请记住,您只编写了一次基类,然后从那时开始,您的代码您每天在阅读和书写的内容看起来更像是我们最初研究的主要方法,这很简洁,可以说,对吗?接下来,您将要学习如何构建共享库,以便可以将所有这些通用类和功能放入可重用的.dll或.so中,以便仅编译业务逻辑,而不编译整个Universe。 :)
答案 9 :(得分:0)
没有理由拥有一个,所以没有任何理由。
答案 10 :(得分:0)
您的演员必须意识到这一点
一个例子
class MyClass {
private:
int someint;
public:
operator const int() {
return this->someint;
}
}