是否可以将任何类对象作为测试表达式传递给任何测试表达式,例如if,while like ifstream对象
Can any class object be passed as test expression for any test expression such as if, while like ifstream object.
在C++中,我可以像ifstream
对象一样使用我的对象作为测试表达式吗。如果没有,为什么?
例如
ifstream ifs ("myfile.txt");
while( ifs ){
//read and process data..
}
我有一个类,我需要重载哪个运算符才能让编译器允许我的对象作为测试表达式传递?
例如
MyClass obj1;
if( obj1 ){
//do something..
}
while( obj1 ){
//do something repeatedly..
}
两者都应该是有效的表达式。
您必须在类中实现bool
重载。类似这样的东西:
class myClass {
public:
explicit operator bool() const { return condition; }
};
它将在if
和while
语句中都起作用。但是,如果编译器不支持C++11,则不能在该重载中使用explicit
关键字。
您有几个选项。可能最好的方法是使operator bool()
过载。像这样:
class A{
public:
operator bool()
{
return flag;
}
private:
bool flag;
};
EDIT:正如评论中所指出的,如果使用C++11
,最好通过在前面添加explicit
关键字来明确运算符。否则,最好使用operator void*()
有很多选项。
您没有;您不必在类中实现operator bool
重载。
而且;It’一般来说不是最好的选择。
最佳:命名状态检查
最好使用名为的状态检查方法。例如,iostream具有fail
成员,因此您可以编写
while( !cin.fail() ) { ... }
对于你自己的班级,它可以看起来像这样:
struct S
{
bool is_good() const { return ...; } // Whatever name.
};
所以:explicit
转换为bool
其次是explicit
转换运算符。将其设为explicit
可以防止if由于将某个对象作为函数参数传递而被无意调用。explicit
转换运算符仍用于条件,因此您可以编写例如
while( cin ) { ... }
它在C++11中调用
explicit operator bool () const { return !fail(); }
对于你自己的班级来说,它可能看起来像
struct S
{
explicit operator bool () const { return ...; }
};
Ungood:隐式转换为"私有"指针类型
第三,如果您使用的编译器不支持explicit
转换,即C++03编译器,并且由于某种莫名其妙的原因,您不希望使用命名检查,这是最佳选择,那么您可以选择一种将意外调用的可能性降至最低的结果类型。
在C++03中,iostreams使用了到void*
(而不是到bool
)的隐式转换。
有些人主张使用"安全布尔习惯用法",其中结果是指向C++03中客户端代码无法访问的类型的指针。
绝对最差:隐式转换为bool
最糟糕的选择是像
struct S
{
operator bool () { return ... }
};
有了这个
从调用代码中看不出要检查的条件是什么。
在传递
S
作为函数参数时,可能会无意中调用运算符。不能对
const
对象调用转换。
添加一个const
只会使它稍微不那么糟糕。
它;It’还是很糟糕
您需要过载operator bool()
才能提供这种行为。但是,只有当转换有合理的语义时,请这样做,这是显而易见的,也是该类所有用户所期望的!
您的编译器将尝试将表达式隐式转换为bool,因此您需要在类中添加一个类型转换运算符,如下所示:
class SomeClass {
operator bool() {
return true; // a boolean expression should go here.
}
}
这将允许您的类被强制转换为布尔类型,因此允许它在if、while等中使用。。。然而,需要注意的是,这允许从您的类型隐式转换为bool,确保这一点很重要。
通常更明智的做法是为行为提供一种方法,例如:
while (myObj.hasMoreElements())
或
if (someObj.isValid())
这使得测试内容一目了然。但是,如果转换为bool是有意义的,请选择它。
您可以重载任意数量的类型转换运算符;这个传统的是operator void*()() const
,返回null假指针和非空指针(传统this
)真的。在C++11中,您也可以重载explicit operator
bool() const
,但如果您的编译器还不允许CCD_ 28;CCD_ 29是整型,如果没有explicit
,它将转换对于任何其他积分类型,都可能导致一些令人惊讶的过载决议。
如果这样做,还应该重载operator!() const
,因此CCD_ 32也得到了很好的定义。
最后,你应该真正反思一下你是否想这样做。ostream类可以逃脱惩罚,因为它们标准的一部分,每个看到、使用和了解它们,而且CCD_ 33习语无处不在。但总的来说,这是对运营商的误导和滥用具有两个以上可能的类的重载各州;CCD_ 34或CCD_适当的
- 测试驱动开发 c++:如何将对象添加到向量中,将歌曲添加到播放列表并对其进行测试
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 在单元测试中,如何在不使用 operator== 的情况下比较两个对象,这可能会错过新成员?
- 类型测试对象的动态数组的这两个声明之间的区别?
- googlemock-如何模拟被测试类所拥有的对象
- 单元测试不可复制的对象
- 为什么谷歌测试/模拟显示 std::unique_ptr 泄露的模拟对象错误?
- 如何实例化多个 set 对象来测试 Set 类的各种构造函数和方法
- 模拟对象与模拟提升::测试
- 谷歌模拟:测试对象的某个属性
- 如何测试共享对象/共享库已正确编译
- 难以在测试中链接项目中的对象文件
- 有什么方法可以测试来自同一类的两个作业对象吗
- 单元测试 - 设置私人成员以获得所需的对象状态
- 测试C++对象的有效性,就好像它是一个指针一样
- 忽略两个C++宏之间的代码(防止创建静态单元测试对象)
- 用于测试对象是否与提升范围兼容的元函数
- 在C++中,如何测试对象是否是父类构造函数中子类的实例?
- 测试对象是否未删除
- cocoa touch -- 测试对象是否是 objective-C 对象