C++ struct和class区别
一 struct继承
最近分析HIDL,在HIDL的生成中google使用了大量的struct继承,比如
struct BnHwLight : public ::android::hidl::base::V1_0::BnHwBase
首先看一下struct和class在继承方面的不同处
1 struct defaults to public access and class defaults to private access.
2 When inheriting, struct defaults to public inheritance and class defaults to privateinheritance. (Ironically, as with so many things in C++, the default is backwards: publicinheritance is by far the more common choice, but people rarely declare structs just to save on typing the "public" keyword.
从上面两处不同看struct默认是public继承,同时成员默认是public。为什么谷歌要使用struct类继承呢? 我觉得有一个原因就是struct默认public继承,而HIDL的接口都是程序自动生成的,为了自动化的便利性,所有成员默认public,方便外部调用。
二 explicit关键字使用
同时在HIDL生成的struct类中,构造函数显示的声明为:
explicit BnHwLight(const ::android::sp<ILight> &_hidl_impl);
看下面这个例子
class Foo
{
public:
// single parameter constructor, can be used as an implicit conversion
Foo (int foo) : m_foo (foo)
{
}
int GetFoo () { return m_foo; }
private:
int m_foo;
};
void DoBar (Foo foo)
{
int i = foo.GetFoo ();
}
int main ()
{
DoBar (42);
}
在main中DoBar的参数是Int类型而不是Foo类,但是Foo类中有讲int转换成Foo的构造函数,因此编译器就使用Foo的构造函数以42为参数转换成Foo类。
如果将Foo的构造函数定义为explicit的话,则在编译阶段就会报错。
添加explicit避免这种隐式变换引起的BUG。
比如我们有MyString(int size)类和构造函数,同时有函数print(const MyString &),当我们调用print(3)的话,不使用explicit的话,默认输出大小为3个空字符的string,而不是输出3.
在hidl_gen中使用explicit也是由于代码是自动生成的,隐式转换可能会存在BUG。