信息发布软件,b2b软件,广告发布软件

标题: 认真学一学C++元素命名的重点难点都在这一目了然了 [打印本页]

作者: 群发软件    时间: 2017-6-14 21:23
标题: 认真学一学C++元素命名的重点难点都在这一目了然了

如果只是编写一些小程序,程序只有几十或几百行,编程风格可能并不重要。然而,如果是和许多人一起进行一定规模的项目开发,或者希望过一段时间之后,还能够快速而准确地理解自己的程序,就必须养成良好的编程习惯。良好的编程风格可以增加程序代码的可读性。编程风格最能体现一个程序员的综合素质。变量的命名规范是编程风格的一项重要内容。

变量的命名规范有很多种。在Windows下开发软件,许多人采用匈牙利命名法,而在Linux环境下,并不建议使用这种方法。


1.linux命名规范

(1)变量名必须有一定的意义,并且意义准确。例如有一个变量用于保存图书的数目,可以命名为number_of_book或者num_of_book。不建议使用i,因为它没有意义。也不建议使用number或book,因为意义不准确。

(2)不建议大小写混用。如定义一个计数变量,int nCount;这在Windows中是一个很好的变量名,其中nCount的首字母n用来说明这个变量的类型是int。但在linux下不建议大小写混合使用,一般标识符只由小写字母,数字和下划线构成。

(3)在失去意义的情况下,尽量使用较短的变量名。例如有一个变量,用于暂时存储一个计数值,把变量命名为tmp_count显然要比this_is_a_temperary_counter好。

(4)不采用匈牙利命名法表示变量的类型。如int nCount;n用于说明变量的类型,在Linux中不建议这样命名变量。

(5)函数名应该以动词开头,因为函数是一组具有特定功能的语句块。比如一个函数,它用于取得外部输入的数值,则可以命名为get_input_number。

(6)尽量避免使用全局变量。全局变量在后面的章节中会介绍。

2.Yii命名规则

Yii 推荐命名变量、函数和类时使用 驼峰风格,即每个单词的首字母大写并连在一起,中间无空格。 变量名和函数名应该使它们的第一个单词全部小写,以使其区别于类名(例如:$basePath, runController(),LinkPager)。

对私有类成员变量来说,我们推荐以下划线作为其名字前缀(例如: $_actionList)。

由于在 PHP 5.3.0 之前不支持名字空间,我们推荐类要通过某种独立的方式命名,以避免和第三方类发生冲突。鉴于此, 所有的 Yii 框架类名以 "C" 作前缀。

一个针对控制器名字的特殊规则是它们必须以单词 Controller 结尾。那么控制器 ID 即类名的首字母小写并去掉单词 Controller。 例如,PageController 类的 ID 就是 page 。这个规则使应用更加安全。它还使控制器相关的URL更加简单(例如 /index.php?r=page/index 而不是 /index.php?r=PageController/index)。

3.QT命名规则

一些规则通常对所有名字都是有用的。首先,就像我之前提到的,别用缩写。甚至很明显的缩写,比如“prev”表示“previous”从长远看也是不划算的,因为用户必须记住哪些词是缩写。

如果API本身不一致,事情自然会变得很糟糕,比如, Qt3有activatePreviousWindow()和fetchPrev()。坚持“没有缩写”的规则更容易创建一致的API。

另一个重要但更加微妙的规则是,在设计类的时候,必须尽力保证子类命名空间的干净。在Qt3里,没有很好的遵守这个规则。比如,拿QToolButton来举例。如果你在Qt3里,对一个QToolButton调用name()、caption()、text()或者textLabel(),你希望做什么呢?你可以在Qt Designer里拿QToolButton试试:

由于对可读性的关注,name在Qt4里被称作objectName,caption变成了windowsTitle,而在QToolButton里不再有单独的textLabel属性。

给类命名

标识一组类而不是单独给每个类找个恰当的名字。比如,Qt4里所有模式感知项目的视图类(model-aware item view classes)都拥有-View的后缀(QListViewQTableViewQTreeView),并且对应基于项目的类都用后缀-Widget代替(QListWidgetQTableWidgetQTreeWidget)。

给枚举类型及其值命名

当声明枚举时,时刻记住,在C++(不像Java和C#)中,使用枚举值不需要类型信息。下面的例子演示了给枚举值起个太过常用的名字所引起的危害:

    namespace Qt    {        enum Corner { TopLeft, BottomRight, ... };        enum CaseSensitivity { Insensitive, Sensitive };        ...    };    tabWidget->setCornerWidget(widget, Qt::TopLeft);    str.indexOf("$(QTDIR)", Qt::Insensitive);

在最后一行,Insensitive是什么意思?一个用于命名枚举值的指导思想是,在每个枚举值里,至少重复一个枚举类型名中的元素:

    namespace Qt    {        enum Corner { TopLeftCorner, BottomRightCorner, ... };        enum CaseSensitivity { CaseInsensitive,                               CaseSensitive };        ...    };    tabWidget->setCornerWidget(widget, Qt::TopLeftCorner);    str.indexOf("$(QTDIR)", Qt::CaseInsensitive);

当枚举值可以用“或”连接起来当作一个标志时,传统的做法是将“或”的结果作为一个int保存,这不是类型安全的。Qt4提供了一个模板类 QFlags<T>来实现类型安全,其中T是个枚举类型。为了方便使用,Qt为很多标志类名提供了typedef,所以你可以使用类型 Qt::Alignment代替QFlags<Qt::AlignmentFlag>。

为了方便,我们给枚举类型单数的名字(这样表示枚举值一次只能有一个标志),而“标志”则使用复数名字。比如:

    enum RectangleEdge { LeftEdge, RightEdge, ... };    typedef QFlags<RectangleEdge> RectangleEdges;

有些情况下,“标志“类使用了单数的名字。这时,枚举类使用-Flag做后缀:

    enum AlignmentFlag { AlignLeft, AlignTop, ... };    typedef QFlags<AlignmentFlag> Alignment;

(这里为啥不是把”标志“类用-Flag做后缀,而是把枚举值做后缀呢?感觉有点混淆……)

给函数和参数命名

给函数命名的一个规则是,名字要明确体现出这个函数是否有副作用。在Qt3,常数函数QString::simplifyWhiteSpace()违反了这个原则,因为它返回类一个QString实例,而不是像名字所提示的那样,更改了调用这个函数的实例本身。在Qt4,这个函数被重命名为QString::simplified()。

参数名是程序员的重要信息来源,虽然在使用API时,并不直接展示在代码里。由于现代IDE在程序员写代码时可以自动显示参数名(就是自动感知或者自动补全之类的功能),值得花时间给头文件里声明的参数一个合适的名字,并且在文档中也使用相同的名字。

给布尔值设置函数(Setter)、提取函数(Getter)和属性命名

给布尔属性的设置函数和提取函数一个合适的名字,总是非常痛苦的。提取函数应该叫做checked()还是isChecked()?scrollBarsEnabled()还是areScrollBarEnabled()?

在Qt4里,我们使用下列规则命名提取函数:

设置函数名字继承自提取函数名,只是移掉了所有前缀,并使用set-做前缀,比如:setDown()还有setScrollBarsEnabled()。属性的名字与提取函数相同,只是去掉了前缀。


一、C++类的定义
    C++中使用关键字 class 来定义类, 其基本形式如下:
class 类名
{

public:
[url=]//行为或属性[/url]
protected:
//行为或属性
private:
//行为或属性


};

示例:
     定义一个点(Point)类, 具有以下属性和方法:
     ■ 属性: x坐标, y坐标
     ■ 方法: 1.设置x,y的坐标值; 2.输出坐标的信息。
实现代码:

class Point
{
public:
     void setPoint(int x, int y);
     void printPoint();

private:
     int xPos;
     int yPos;
};  
代码说明:
     上段代码中定义了一个名为 Point 的类, 具有两个私密属性, int型的xPos和yPos, 分别用来表示x点和y点。

     在方法上, setPoint 用来设置属性, 也就是 xPos 和 yPos 的值; printPoint 用来输出点的信息。   

1 数据抽象和封装

     抽象是通过特定的实例抽取共同特征以后形成概念的过程。一个对象是现实世界中一个实体的抽象,一个类是一组对象的抽象。     封装是将相关的概念组成一个单元,然后通过一个名称来引用它。面向对象封装是将数据和基于数据的操作封装成一个整体对象,对数据的访问或修改只能通过对象对外提供的接口进行。


2 类定义
     几个重要名词:
(1) 类名
     遵循一般的命名规则; 字母,数字和下划线组合,不要以数字开头。
(2) 类成员
     类可以没有成员,也可以定义多个成员。成员可以是数据、函数或类型别名。所有的成员都必须在类的内部声明。
     没有成员的类是空类,空类也占用空间。
class People
{
};
sizeof(People) = 1;   
(3) 构造函数
     构造函数是一个特殊的、与类同名的成员函数,用于给每个数据成员设置适当的初始值。

(4) 成员函数
     成员函数必须在类内部声明,可以在类内部定义,也可以在类外部定义。如果在类内部定义,就默认是内联函数。

3 类定义补充
3.1 可使用类型别名来简化类
     除了定义数据和函数成员之外,类还可以定义自己的局部类型名字。
     使用类型别名有很多好处,它让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。
class People
{
public:
     typedef std::string phonenum; [url=]//电话号码类型[/url]

phonenum phonePub; //公开号码
private:      
phonenum phonePri;//私人号码
};

3.2 成员函数可被重载
     可以有多个重载成员函数,个数不限。
3.3 内联函数
     有三种:
(1)直接在类内部定义。
(2)在类内部声明,加上inline关键字,在类外部定义。
(3)在类内部声明,在类外部定义,同时加上inline关键字。注意:此种情况下,内联函数的定义通常应该放在类定义的同一头文件中,而不是在源文件中。这是为了保证内联函数的定义在调用该函数的每个源文件中是可见的。
3.4 访问限制
     public,private,protected 为属性/方法限制的关键字。
3.5 类的数据成员中不能使用 auto、extern和register等进行修饰, 也不能在定义时进行初始化
     如 int xPos = 0; //错;
例外:
          静态常量整型(包括char,bool)数据成员可以直接在类的定义体中进行初始化,例如:
          static const int ia= 30;


4 类声明与类定义
4.1 类声明(declare)
class Screen;
      在声明之后,定义之前,只知道Screen是一个类名,但不知道包含哪些成员。只能以有限方式使用它,不能定义该类型的对象,只能用于定义指向该类型的指针或引用,声明(不是定义)使用该类型作为形参类型或返回类型的函数。
void Test1(Screen& a){};void Test1(Screen* a){};
4.2 类定义(define)
     在创建类的对象之前,必须完整的定义该类,而不只是声明类。所以,类不能具有自身类型的数据成员,但可以包含指向本类的指针或引用。
class LinkScreen
{

public:
          Screen window;
          LinkScreen* next;
          LinkScreen* prev;
}; [url=]//注意,分号不能丢[/url]
     因为在类定义之后可以接一个对象定义列表,可类比内置类型,定义必须以分号结束:
class LinkScreen{ /* ... */ };
class LinkScreen{ /* ... */ } scr1,scr2;
     
5 类对象
     定义类对象时,将为其分配存储空间。
     Sales_item item; //编译器分配了足以容纳一个 Sales_item 对象的存储空间。item 指的就是那个存储空间。

6 隐含的 this 指针
     成员函数具有一个附加的隐含形参,即 this指针,它由编译器隐含地定义。成员函数的函数体可以显式使用 this 指针。
6.1 何时使用 this 指针
     当我们需要将一个对象作为整体引用而不是引用对象的一个成员时。最常见的情况是在这样的函数中使用 this:该函数返回对调用该函数的对象的引用。
class Screen
{
...
public:
      Screen& set(char);
};

Screen& Screen::set(char c)
{
      contents[cursor] = c;
      return *this;
}

7 类作用域
     每个类都定义了自己的作用域和唯一的类型。

     类的作用域包括:类的内部(花括号之内), 定义在类外部的成员函数的参数表(小括号之内)和函数体(花括号之内)。
class Screen
{
//类的内部
...
};
//类的外部
char Screen::get(index r, index c) const
{
     index row = r * width;      // compute the row location
     return contents[row + c];   // offset by c to fetch specified character
}

     注意:成员函数的返回类型不一定在类作用域中。可通过 类名::来判断是否是类的作用域,::之前不属于类的作用域,::之后属于类的作用域。例如
Screen:: 之前的返回类型就不在类的作用域,Screen:: 之后的函数名开始到函数体都是类的作用域。

class Screen
{
public:
     typedef std::string::size_type index;
     index get_cursor() const;
};
Screen::index Screen::get_cursor() const   //注意:index前面的Screen不能少
{
     return cursor;
}
     该函数的返回类型是 index,这是在 Screen 类内部定义的一个类型名。在类作用域之外使用,必须用完全限定的类型名 Screen::index 来指定所需要的 index 是在类 Screen 中定义的名字。


C++程序中的许多元素都有用来表示它们的名称(也称为标识符)。在C++程序中,可以命名的5种元素是:

  (1) 函数。函数是自包含的、可执行代码的命名块。第8章将详细讨论如何定义函数。

  (2) 变量。变量是内存中的指定区域,用于存储数据项。第2章将论述变量。

  (3) 类型。类型是可以存储的数据种类。例如类型int用于存储整数。第2章和后续的章节将介绍类型,尤其是第11和12章。

  (4) 标签。标签提供了表示特定语句的方式。它们很少使用,第4章将详细介绍。

  (5) 命名空间。命名空间是用一个集合名称标识程序中一组命名项的方式。这听起来可能让人混淆,但不必担心,稍后就介绍命名空间,第10章将详细论述。

  在大多数现代C++编译器中,名称只能包含大小写字母、下划线和0~9的数字。ANSI标准还允许在名称中包含通用字符集(Universal Character Set)(稍后介绍)中的字符,但一般不需要这项功能。

  名称必须由允许的字符组成,不要在名称的中间加上空白字符(空格、制表符等),否则,编译器就不会把该名称看做是一个名称,而是看做两个名称,从而导致处理不正确。另一个限制是名称不能以数字开头。下面是一些合法的名称例子:

  value2 Mephistopheles BettyMay Earth_weight PI

  下面的名称就不合法:

  8Ball Mary-Ann Betty May Earth-weight 2PI

  提示:

  包含两个下划线的名称,或者以下划线开头,后跟一个大写字母的名称,是C++标准库的保留名称,在程序中不应使用这类名称。编译器不会检查这类名称,用户只能在程序出错时发现有一个冲突的名称。

  我们将在使用名称时进一步讨论它们,第2章讨论变量时就开始讨论名称。

  命名空间

  在上面的简单C++程序中,有一行代码没有解释。为了理解这行代码,需要知道什么是命名空间。为了说明命名空间的含义,下面先讨论名称。上面C++程序中还没有解释的代码行如下:

  using namespace std;

  命名空间的名称有点像姓氏。家庭中的每个成员都有自己的姓名,在大多数家庭中,每个家庭成员都有一个惟一的名字。在Smith家中,有Jack、Jill、Jean和Jonah。在家庭成员之间,用名字来指代每个人。但是,其他家庭的成员可能与Smith家的成员有相同的名字。例如,在Jones家中,其成员的名字是John、Jean、Jeremiah和Jonah。Jeremiah Jones在称呼Jean时,显然是指Jean Jones。如果他想指代Smith家中的Jean,就要使用全名Jean Smith。如果不是这两个家庭的成员,就只能使用每个人的全名来指代他本人,例如Jack Smith或Jonah Jones。

  这就是命名空间的作用。命名空间的名称类似于姓氏。在命名空间内部,可以使用其成员的名字。在命名空间的外部,就只能把某个实体的名字和命名空间的名称组合起来,表示该命名空间中的实体。命名空间的目的是提供一种机制,使大程序的各个部分中因出现重名而导致冲突的可能性降到最低。一般情况下,一个程序中包含几个不同的命名空间。

  C++标准库中的实体都是在命名空间std中定义的,所以标准库中的所有实体名都用std来限定。cout的全名就是std::cout,其中的两个冒号有一个非常好听的名称:范围解析运算符,稍后详述。在这个例子中,该运算符把命名空间的名称std和流的名称cout分隔开来。

  在这个简单的C++程序中,开头的using指令表示我们希望在每次引用命名空间std中的元素时,不指定命名空间的名称。继续前面的类推,使程序文件成为std家族的一组荣誉成员,就可以只用名字来引用每个成员了。其优点之一是不需要把cout表示为std::cout,这样程序代码就更简单。如果省略using指令,就必须把输出语句写为:

  std::cout <<"The best place to start is at the beginning";





作者: xoxo110    时间: 2017-6-15 21:05
,制作完美。
作者: weipinzongmeng    时间: 2017-6-22 16:35
家可以看看效果
作者: w8899    时间: 2017-6-22 17:19
及时做出评价,系统默认好评!
作者: lalajie    时间: 2017-6-23 00:03
好,页面设计很满意,而且也很快,非常有效率,第一次买,遇到这么好的卖家,这么高效的服务,真的太幸运了,太谢
作者: dongwuhua    时间: 2017-6-23 00:04
不错不错,您辛苦了。。。
作者: ziyang701    时间: 2017-6-23 01:35
和5号笨蛋服务非常好
作者: 都敏俊系    时间: 2017-6-27 00:13
的用心,有耐心,下次再合作咯。
作者: ekmci    时间: 2017-7-2 20:08
,价格也便宜,完全超出我的预期,很好很强大,是我想要的后台
作者: 694012770    时间: 2017-7-7 09:12
还是挺快的。客服回答问题也非常快,没有不理人的情况,需要做什么修改也都非常快的给解决的,价格也合理。还会继续合作的,
作者: dccmdy    时间: 2017-7-10 22:26
果非常满意,特别是客服千羽超级赞,沟通很有耐心,专业素质理解能力非常高。
作者: 脱颖而出    时间: 2017-7-13 02:39
7很给力。做东西很快,效果也棒很好@
作者: kevin3898    时间: 2017-7-13 08:05
卖家!不厌其烦的解释,非常愉快的交易经历!




欢迎光临 信息发布软件,b2b软件,广告发布软件 (http://www.postbbs.com/) Powered by Discuz! X3.2