导读

一、术语

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为名
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值