此处较为注意的是std::size_t,有些人喜欢节俭,一般写成size_t,size_t不单单存在于std内也存在c的头文件中,还可能是global作用域内,所以此处加上std更为规范,说明我是引用std中的。
一个函数的签名等同于该函数的类型。例如numDigits函数的签名是std::size_t (int),也就是说“这个函数获得一个int并返回一个std::size_t”。C++对签名式的官方定义并不包括函数的返回类型,这本书把返回类型视为签名的一部分,这样比较有帮助。
对对象而言,定义式就是编译器对此对象拨发内存的地点。对function或function template而言,定义式提供了代码本体。对class或class template而言,定义式列出他们的成员,
此处要注意的是explicit声明,这个关键词的用意是阻止他们被用来执行隐士类型转换(implicit type conversions),但它们认可被用来进行显示类型转换(explicit type conversions)
void doSomething(B bObject);//函数,接受一个类型为B的对象 BbObj1; //一个类型为B的对象 doSomething(bObj1); //传递一个B给doSomething函数 B bObj2(28); //没问题 doSomething(28); //不行!此处不能用隐式转换 doSomething(B(28)); //可以只要不是特意设计构造函数处理隐式转换,推荐将构造函数声明为explicit,因为explicit进制编译器执行非预期的类型转换。还有些特殊的方式初始化对象,如copy构造函数“以同型初始化自我对象”
class Widget{ public: Widget(); Widget(const Widget& rhs); Widget& operator=(const Widget& rhs); }; Widget w1; //调用default函构造函数 Widget w2(w1); //调用copy构造函数 w1=w2; //调用copy assignment操作符区别copy构造函数和copy赋值操作很简单,如果一个新对象被定义,一定有个构造函数被调用,不可能是copy assignment。如果没有新对象被定义,就不会有构造函数被调用,那么当然就是copy assignment。
例如
int* p = 0; //空指针 std::cout << *p; //对一个null指针取值会导致不明确行为 char name[] = "Darla";//name是个数组,大小为6(尾端是null) char c= name[10]; //指向一个无效的数组索引导致不明确行为