一、术语
1. 声明式:告诉编译器某个东西的名称和类型。
例如:
extern int x; //对象(object)声明式
std::size_t numDigits(int number);//函数(function)声明式
class Widget; //类(class)声明式
template<typename T> //模板(template)声明式
class Graph
此处较为注意的是std::size_t,有些人喜欢节俭,一般写成size_t,size_t不单单存在于std内也存在c的头文件中,还可能是global作用域内,所以此处加上std更为规范,说明我是引用std中的。
2. 签名式:函数参数和返回类型。
一个函数的签名等同于该函数的类型。例如numDigits函数的签名是std::size_t (int)
,也就是说“这个函数获得一个int并返回一个std::size_t”。C++对签名式的官方定义并不包括函数的返回类型,这本书把返回类型视为签名的一部分,这样比较有帮助。
3. 定义式:提供编译器一些声明式所遗漏的细节。
对对象而言,定义式就是编译器对此对象拨发内存的地点。对function或function template而言,定义式提供了代码本体。对class或class template而言,定义式列出他们的成员,
例如:
int x; //对象的定义式
std::size_t numDigits(int number)//函数的定义式
{
std::size_t digitsSoFar=1;
while(number/=10!=0) ++digitsSiFar;
return digitsSoFar;
}
class Widget{ //class的定义式
Widget();
~Widget();
...
};
template<typename T>
class GraphNode{
public:
GraphNode();
~GraphNode();
...
};
4. 初始化:给予对象初值。
class A{
public:
A();
}
class B{
public:
explicit B(int x=0,bool b=ture);
}
class C{
public:
explicit C(int x);
}
此处要注意的是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。
5. 不明确的定义
例如
int* p = 0; //空指针
std::cout << *p; //对一个null指针取值会导致不明确行为
char name[] = "Darla";//name是个数组,大小为6(尾端是null)
char c= name[10]; //指向一个无效的数组索引导致不明确行为
二、命名习惯
- 常用到如
lhs(left-hand side)
和rhs(right-hand side)
- 指向一个T类型的对象指针命名为pt,意思是
point-to-T
Widget* pw; //pw:ptr-to-Widget.
class Airplane;
Airplane* pa; //pa:ptr-to-Airplane.
class GameCharacter;
GameCharacter* pgc; //pgc="ptr-to-GameCharacter"
- 指向一个T类型的对象引用命名为rt,意思是
reference-to-T
Widget& pw; //pw:ref-to-Widget.
class Airplane;
Airplane& pa; //pa:ref-to-Airplane.
class GameCharacter;
GameCharacter& pgc; //pgc="ref-to-GameCharacter"
- 当讨论成员函数时,也可以mf为名