规则:
应该将修饰符* 和 &紧靠变量名。例如:int *a; int &a;
类的版式:
类可以将数据和函数封装起来,其中函数是表示类的行为。也可以称为是服务。类提供了关键字public ,protect ,private用于声明哪些是公共的,哪些是保护的,哪些是 私有的。这样可以让类隐藏必要的东西。
类的版式主要有两种版式:
(1):第一种将privte类型的数据 写在前面,将public类型的数据写在后面。采用这种版式的程序员主张“以数据为中心,”重点关注类的结构。
(2):第二种版式是将public类型写在前面。将private写在后面。这种版式的程序员主张“以行为为中心”。重点关注的是类应该提供什么样的接口(或者服务)。
我建议大家采用“以行为为中心的”的这种类的 版式。因为这样设计类的时候。首先考虑的类可以提供什么洋的服务。而且方便用户阅读。
空行:
空行起着分隔程序段落的作用。
(1):在给个类的声明之后,函数的定义之后,都要加上空行。
(2):在一个函数体内,逻辑关系密切的相关语句之间不可以加上空行。
代码行:
(1):一行代码指做一件事情。例如:只声明一个变量。
(2);if ,for while,do等语句自占一行。执行语句不能紧跟其后。
建议:在定义变量的同时。初始化该变量。
如果变量的引用和定义的地方比较远,那么很容易就会忘记了变量的初始化。如果引用了一个没有初始化的变量,那么很有可能就会引起错误。
代码行内的空格:
(1);关键字之后要有空格。向const ,virtual,case等关键字后面至少要留一个空格。否则的话,无法辨认关键字。象if.while, for等关键字后面紧跟一个空格在跟“(”以显示关键字的。
(2):函数名之后不要留空格,紧跟“(”以和关键字区别。
对齐:
程序的分界符“{”和"}"应该独占一行并且位于一列。
头文件由三部分组成:
1:头文件开头出的版本和版权的 声明。
2:预处理块。
3:函数和类的结构声明等。
规则:
(1): 为了防止头文件被重复的引用,应该使用#ifndef/define/endif结构产生与处理模块。
(2):用#include<filename.h>来引用标准库的头文件(编译器将从标准库目录开始搜索)。
(3):用#include"filename.h"来引用非标准库的头文件(编译器将从用户工作的目录开始搜索)
建议:头文件中一般只存放“声明”,而不存放“定义”
定义文件的结构:
定义文件的 内容有由三部分组成:
(1): 定义文件开头处的版本和版权;
(2):对一些头文件的引用;
(3):程序的实现体(包括数据和代码)
头文件的作用:
(1):通过头文件来调用库功能。在很多场合源代码不能(或者不准)提供给用户。只提供给用头文件或者二进制的库。用户只需要按照头文件中的接口的声明来调用库功能。而不必关心接口是如何实现的。编译器会从库中提取相应的代码。
(2): 头文件可以用来加强类型安全检查。如果某个接口被实现或者被实用的时候,其方式和在头文件中的声明不一致的时候,编译器就会报错。这一简单的规则可以大大的减轻程序员调试和改错的负担。
目录结构:
如果一个软件的头文件比较多(超过10个),就应该把头文件和定义文件分开。分别保存在不同的目录之中。以便于维护。
例如:可以将头文件保存在inluude目录之中。将定义文件保存在source文件之中。
如果某些头文件是私有的,不会被程序直接引用,为了加强信息隐藏。那么可以把这些头文件和定义文件放在同一目录之中。
指针中存有另一个对象的地址,使我们可以间接的操作这个对象。
指针的典型用法是构建一个连接的数据结构,例如:链表(list)和数(tree)。并管理在程序运行的过程中动态分配的对象。以及作为函数参数类型。主要用来传递数组和大型类的对象。
每个指针都有相关的类型。
不同数据类型的指针之间的区别不在于指针的表示上,也不是指针所持有的值(地址)。——对于所有类型的指针这两个方面都是一样的。不同之处在于指针所指的对象的类型上。针织类型可以指定编译器咋样解释特定内存上的指定的内容,以及该内存区域因该跨越多少内存单元。
变量名,即变量的标识符,可以由字符,数字,以及下划线来组成。他必须以字符或者下划线来开头,并且区分大小写。
语言本身没有对变量名做什么限制。但是为了用户着想,他不应过长。
c++保留了一些词用作关键字。关键字标识符不能在作为标识符在程序中使用了。
对于命名对象有很多已经普遍接受的习惯。主要考虑的因素的是程序的可读性。
第一:对象的命名一般用小写。
第二:标识符通常用容易记忆的名字。
第三:对于多词构成的标识符一般在词的中间加上下划线。
对象的定义:
一个简单的对象的定义由一个类型指示符后面加上一个名字构成,以分号结束。
例如: int aaaaa;
当同类型的多个标识符被定义的时候,我们可以在类型指示符后面用逗号隔开。
一个简单的定义指定了变量的类型和标识符。他并不提供初始值。
如果一个变量是在全局域(globe scope)中定义的,那么系统会保证给他一个初始值0。如果一个变量是在一个局部域中定义的,或者通过一个new 动态分配的,那么系统不会向它提供初始值0。这些对象被称为未初始化(uninitialized),未初始化的对象不是没有值,而是对象的值未被定义。
因为使用未初始化的对象是个很常见的 错误,并且很难被发现。所以建议为每个定义的对象进行初始化。
类机制通过缺省构造函数提供了类对象的自动初始化。
例如:
int main()
{
int val;////////未被初始化的值。
string project;//////通过string类的缺省的构造函数进行了初始化。
}
val是一个未被初始化的局部变量。
但是project是一个已经被初始化的类对象——被string类缺省的构造函数自动初始化。
初始化一个值可以在对象定义的时候进行。
c++支持两种形式的初始化。
第一种是使用赋值符号的现实的操作。
如:
int val=111;
string project="ssssss";
隐式形式中,初始化值被放在括号中。
int val(111);
string project("sssssss");
在对象的定义之中,当对象的标识符在定义中出现后,对象名马上就是可见的了。因此用对象初始化他自己是合法的,只是这样做不是明智的。
例如:int val=val;///////合法,但是不是明智的。
另外,每种内置数据类型都支持一种特殊的构造函数。可将对象初始化为0。
/////设置val为0。设置dval为0.0。
int val =int();
double dval=double();
下列的定义中:
int()
vector <int>ival(10);
函数int()自动被应用到ival包含的10个元素上。
对象可以用任意复杂的表达式来初始化,也可以用返回值
变量为我们提供了一个有名字的内存存贮空间。可以通过程序对其进行 读写,处理操作。
c++中给个符号变量都有一个符号类型与之对应。这个类型决定了相关内存的大小,类型,布局,能够存贮在该内存值的范围。以及可以以用到其上的操作集。我们也可以把变量说成是对象(object)
。
变量和文字常量都有存贮区,并且都有相关的类型。区别在于变量是可以寻址的(adressable)常量文字是不可以寻址的(nonadressable),每一个变量都有两个值与之联系着,
1:数据值。存贮在内存的某个存贮区之中。有时候这个数据值也被称为是右值(rvalue).我们可以认为右值是被读取的值。文字常量和变量都可以被用来做右值。
2:它的地址值。即存贮它数据值的那块内存的地址。它有时候被称为左值(lvalue)。我们也可以认为左值的意思是位置值。文字常量不能被用作左值。
变量的定义会引起相关内存的分配。因为一个对象只能有一个存贮位置,所以一个对象只能被定义一次。如果在一个文件中定义的对象需要在另一个文件中被访问,那么就会出现问题。
在c++中,对象在使用之前必须知道对象,引用一个未知的对象会引起编译器的错误。
如果一个对象在另一个 文件中声明着,我们想在这个文件中来使用这个对象,但是又不能在这个文件中在声明相同的对象。那么我们可以使用extern关键字来声明这个对象。
例如; file module.c
string aaaaa;
///定义了对象aaaaa
file module1.c
////需要使用对象aaaaa.,
////声明对象aaaaa,使程序知道它。但是又不能引入第二个定义。
extern string aaaaa;
对象声明是使程序知道对象的类型和名字。它由关键字extern后面跟对象的类型和对象的名字构成。
声明不是定义,不会引起内存的分配。实际上它只是说明了在程序之外的某处有这个变量的定义。
虽然一个程序中只能包含一个对象的定义,但是可以包含很多的对象声明。
比较好的做法是: 不是在每个要使用的文件中都单独提供一个声明。而是在在头文件中声明这个对象,然后在需要声明这个对象的时候包含这个头文件就好了。按照这个做法。如果需要修改对象的声明只需要修改一次。就能维持多个使用这个对象的声明文件的一致性。
面相对象的程序设计扩展了给予对象的程序设计。可以提供类型和子类型的关系。这个是通过一种称作继承(inheritance)的机制来实现的。