Creative Commons License
本Blog采用 知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议 进行许可。 —— Fox <游戏人生>

游戏人生

游戏人生 != ( 人生 == 游戏 )
站点迁移至:http://www.yulefox.com。请订阅本博的朋友将RSS修改为http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

[译]Google C++编程风格指南(二)

Posted on 2008-07-14 15:49 Fox 阅读(7607) 评论(27)  编辑 收藏 引用 所属分类: T技术碎语

原文地址:

  • 作用域

1. 命名空间(Namespaces)

在.cc文件中,提倡使用不具名的命名空间(unnamed namespaces,译者注:不具名的命名空间就像不具名的类一样,似乎被介绍的很少:-()。使用具名命名空间时,其名称可基于项目或路径名称,不要使用using指示符。

定义:命名空间将全局作用域细分为不同的、具名的作用域,可有效防止全局作用域的命名冲突。

优点:命名空间提供了(可嵌套)命名轴线(name axis,译者注:将命名分割在不同命名空间内),当然,类也提供了(可嵌套)的命名轴线(译者注:将命名分割在不同类的作用域内)。

举例来说,两个不同项目的全局作用域都有一个类Foo,这样在编译或运行时造成冲突。如果每个项目将代码置于不同命名空间中,project1::Foo和project2::Foo作为不同符号自然不会冲突。

缺点:命名空间具有迷惑性,因为它们和类一样提供了额外的(可嵌套的)命名轴线。在头文件中使用不具名的空间容易违背C++的唯一定义原则(One Definition Rule (ODR))

结论:根据下文将要提到的策略合理使用命名空间。

1) 不具名命名空间(Unnamed Namespaces)

在.cc文件中,允许甚至提倡使用不具名命名空间,以避免运行时的命名冲突:

namespace {                                   // .cc 文件中

// 命名空间的内容无需缩进
enum { UNUSED, EOF, ERROR };          // 经常使用的符号
bool AtEof() { return pos_ == EOF; }   // 使用本命名空间内的符号EOF

}  // namespace

然而,与特定类关联的文件作用域声明在该类中被声明为类型、静态数据成员或静态成员函数,而不是不具名命名空间的成员。像上文展示的那样,不具名命名空间结束时用注释// namespace标识。

不能在.h文件中使用不具名命名空间。

2) 具名命名空间(Named Namespaces)

具名命名空间使用方式如下:

命名空间将除文件包含、全局标识的声明/定义以及类的前置声明外的整个源文件封装起来,以同其他命名空间相区分。

// .h文件
namespace mynamespace {

// 所有声明都置于命名空间中
// 注意不要使用缩进
class MyClass {
public:
  ...
  void Foo();
};

}  // namespace mynamespace

// .cc文件
namespace mynamespace {

// 函数定义都置于命名空间中
void MyClass::Foo() {
  ...
}

}  // namespace mynamespace

通常的.cc文件会包含更多、更复杂的细节,包括对其他命名空间中类的引用等。

#include "a.h"

DEFINE_bool(someflag, false, "dummy flag");

class C;  // 全局命名空间中类C的前置声明
namespace a { class A; }  // 命名空间a中的类a::A的前置声明

namespace b {

...code for b...                // b中的代码

}  // namespace b

不要声明命名空间std下的任何内容,包括标准库类的前置声明。声明std下的实体会导致不明确的行为,如,不可移植。声明标准库下的实体,需要包含对应的头文件。

最好不要使用using指示符,以保证命名空间下的所有名称都可以正常使用。

// 禁止——污染命名空间
using namespace foo;

在.cc文件、.h文件的函数、方法或类中,可以使用using。

// 允许:.cc文件中
// .h文件中,必须在函数、方法或类的内部使用
using ::foo::bar;

在.cc文件、.h文件的函数、方法或类中,还可以使用命名空间别名。

// 允许:.cc文件中
// .h文件中,必须在函数、方法或类的内部使用

namespace fbz = ::foo::bar::baz;

2. 嵌套类(Nested Class)

当公开嵌套类作为接口的一部分时,虽然可以直接将他们保持在全局作用域中,但将嵌套类的声明置于命名空间中是更好的选择。

定义:可以在一个类中定义另一个类,嵌套类也称成员类(member class)

class Foo {

private:
  // Bar是嵌套在Foo中的成员类
  class Bar {
    ...
  };

};

优点:当嵌套(成员)类只在被嵌套类(enclosing class)中使用时很有用,将其置于被嵌套类作用域作为被嵌套类的成员不会污染其他作用域同名类。可在被嵌套类中前置声明嵌套类,在.cc文件中定义嵌套类,避免在被嵌套类中包含嵌套类的定义,因为嵌套类的定义通常只与实现相关。

缺点:只能在被嵌套类的定义中才能前置声明嵌套类。因此,任何使用Foo::Bar*指针的头文件必须包含整个Foo的声明。

结论:不要将嵌套类定义为public,除非它们是接口的一部分,比如,某个方法使用了这个类的一系列选项。

3. 非成员函数(Nonmember)、静态成员函数(Static Member)和全局函数(Global Functions)

使用命名空间中的非成员函数或静态成员函数,尽量不要使用全局函数。

优点:某些情况下,非成员函数和静态成员函数是非常有用的,将非成员函数置于命名空间中可避免对全局作用域的污染。

缺点:将非成员函数和静态成员函数作为新类的成员或许更有意义,当它们需要访问外部资源或具有重要依赖时更是如此。

结论:

有时,不把函数限定在类的实体中是有益的,甚至需要这么做,要么作为静态成员,要么作为非成员函数。非成员函数不应依赖于外部变量,并尽量置于某个命名空间中。相比单纯为了封装若干不共享任何静态数据的静态成员函数而创建类,不如使用命名空间。

定义于同一编译单元的函数,被其他编译单元直接调用可能会引入不必要的耦合和连接依赖;静态成员函数对此尤其敏感。可以考虑提取到新类中,或者将函数置于独立库的命名空间中。

如果你确实需要定义非成员函数,又只是在.cc文件中使用它,可使用不具名命名空间或static关联(如static int Foo() {...})限定其作用域。

4. 局部变量(Local Variables)

将函数变量尽可能置于最小作用域内,在声明变量时将其初始化。

C++允许在函数的任何位置声明变量。我们提倡在尽可能小的作用域中声明变量,离第一次使用越近越好。这使得代码易于阅读,易于定位变量的声明位置、变量类型和初始值。特别是,应使用初始化代替声明+赋值的方式。

int i;
i = f();        // 坏——初始化和声明分离
nt j = g();   // 好——初始化时声明

注意:gcc可正确执行for (int i = 0; i < 10; ++i)(i的作用域仅限for循环),因此其他for循环中可重用i。if和while等语句中,作用域声明(scope declaration)同样是正确的。

while (const char* p = strchr(str, '/')) str = p + 1;

注意:如果变量是一个对象,每次进入作用域都要调用其构造函数,每次退出作用域都要调用其析构函数。

// 低效的实现
for (int i = 0; i < 1000000; ++i) {
  Foo f;  // 构造函数和析构函数分别调用1000000次!
  f.DoSomething(i);
}

类似变量放到循环作用域外面声明要高效的多:

Foo f;  // 构造函数和析构函数只调用1次
for (int i = 0; i < 1000000; ++i) {
  f.DoSomething(i);
}

5. 全局变量(Global Variables)

class类型的全局变量是被禁止的,内建类型的全局变量是允许的,当然多线程代码中非常数全局变量也是被禁止的。永远不要使用函数返回值初始化全局变量。

不幸的是,全局变量的构造函数、析构函数以及初始化操作的调用顺序只是被部分规定,每次生成有可能会有变化,从而导致难以发现的bugs。

因此,禁止使用class类型的全局变量(包括STL的string, vector等等),因为它们的初始化顺序有可能导致构造出现问题。内建类型和由内建类型构成的没有构造函数的结构体可以使用,如果你一定要使用class类型的全局变量,请使用单件模式(singleton pattern)

对于全局的字符串常量,使用C风格的字符串,而不要使用STL的字符串:

const char kFrogSays[] = "ribbet";

虽然允许在全局作用域中使用全局变量,使用时务必三思。大多数全局变量应该是类的静态数据成员,或者当其只在.cc文件中使用时,将其定义到不具名命名空间中,或者使用静态关联以限制变量的作用域。

记住,静态成员变量视作全局变量,所以,也不能是class类型!

______________________________________

译者:这一篇主要提到的是作用域的一些规则,总结一下:

1. .cc中的不具名命名空间可避免命名冲突、限定作用域,避免直接使用using提示符污染命名空间;

2. 嵌套类符合局部使用原则,只是不能在其他头文件中前置声明,尽量不要public;

3. 尽量不用全局函数和全局变量,考虑作用域和命名空间限制,尽量单独形成编译单元;

4. 多线程中的全局变量(含静态成员变量)不要使用class类型(含STL容器),避免不明确行为导致的bugs

作用域的使用,除了考虑名称污染、可读性之外,主要是为降低耦合度,提高编译、执行效率。

Feedback

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2008-07-20 23:17 by spirit
对下面这句话不是很理解:
“不要声明命名空间std下的任何内容,包括标准库类的前置声明。声明std下的实体会导致不明确的行为,如,不可移植。声明标准库下的实体,需要包含对应的头文件。”
能否解释的更清楚一些?

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2008-07-21 10:13 by Fox
stl之所以会将所有实体的定义和实现置于std命名空间下,正是为了避免出现命名冲突(string\map\vector\list等等),如果使用了using或前置声明之类,效果等同于将其纳入当前命名空间,所以说会导致不明确的行为,命名冲突、不可移植,不知道你同意否?

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2008-07-21 20:42 by skybird
解释的还算明白,可以补充下,不声明的结果就是使用的时候要明示所在命明空间,如 std::string ,这样做呢,就是麻烦而已,不过避免了不可预知的冲突,除非你对std里的所有都系都了如指掌:)

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2010-03-05 22:04 by Horne30Lynda
Did you ever know that the famous essay writing service could complete the <a href="http://www.supremeessays.com/map.html">sitemap</a> of perfect quality, hence this became worth to buy term papers at that place.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2010-04-05 21:32 by ringtones
People guess that the free downloadable ringtones should be available in the ringtones services and this is truth.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2010-05-13 14:31 by Supra shoes
<P>The <A title="Supra shoes" href="http://www.supramvp.com/supra-strapped-ns-c-5.html"><STRONG>Supra Strapped NS</STRONG></A> shoes are one of the top skateboarding shoes on the block. </P>It is a good chance for you to buy now .Nowadays ,we published a new kind of <A title="Air Jordan" href="http://www.jordanmvp.com/"><EM>Air Jordan</EM></A> ,that is the <EM>Air Jordan Force line</EM> .They are so good that when you see it , you will like it and are willing to own

# WTY  回复  更多评论   

2010-08-05 09:40 by cosplay
@Supra shoes

# [Translation] Google C + + programming style guidelines (b)  回复  更多评论   

2010-10-21 14:24 by TermPapers
The Google C + + programming style guidelines is a really good thing for so many peoples who wants to know about the C + + and the the style guidelines is really a thing which is new and having the information about it is really wounder full.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2010-10-27 04:07 by asd
<a href="http://www.pokerenfrancais.eu/">poker ligne</a> - it's your first step to rich and beautiful life.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-01-04 18:25 by Watch Online

Thanks for a nice post you have given to us with such an large collection of information. Great work you have done by sharing them to all.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-03-16 11:53 by Designer Handbags
Generally, artist handbags are accessible in various colors, so when you ever locate a design you like but would favor another color, just click the image and see what's available.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-03-21 17:08 by wholesale replica handbags
A good certainly false Louis Vuitton is often a back-firer. That's the reason you'll want to consider excellent reproduction shopping bags which function its name in addition to objective from good price ranges.

# great  回复  更多评论   

2011-04-10 10:46 by Ralph Lauren Polo Shirts
Even although Ralph Lauren is known mostly for his revolutionary clothes styles, he can be considered a pretty successful and respected figure in the fragrance industry.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-05-04 08:46 by herve leger london
This is very interesting. I actually enjoy your writing style and your word choice more than anything Smile

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-05-05 14:07 by air max 90
thank you for the informative post and keep up the good work

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-05-07 14:46 by ray ban aviator
Good work, always enjoy reading your stuff

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-05-09 14:10 by Givenchy jewelry
Of all the couture houses Givenchy is the one that continually produces the most awe-inspiring collections in my eyes at least.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-05-12 14:33 by chaussures air max

cc~~~~~


J'ai passé ... Continuer ...

mais je vous remercie pour votre partage ^o^

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2011-05-13 11:33 by maison martin margiela
n his first winter collection, displayed in 1988, shards from broken plates had been worked into shirts.

# re: 重写atoi函数  回复  更多评论   

2011-10-11 11:35 by north face sale
声明std下的实体会导致不明确的行为

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2012-02-15 11:43 by shox pas cher
这是一个非常好的博客,教会我很多,谢谢分享、

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2012-03-13 04:50 by phone number lookup
本文阐述了一个主题,我以为我知道一切关于一些新的光。我喜欢阅读新的观点和对事物,喜欢读书,写在这里。让我们来看看本网站所提供的!

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2012-03-18 16:58 by Buy a Custom Essay
Do you have samples of custom writing frauds? University students who are going to to Buy Essay Papers should acknowledge which term papers writing provider to choose.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2012-03-18 17:02 by essay writing
I do know that people have to know about this good post and essay writing. At the term paper writing services it is really easy to buy pre-finished essays and custom essay just about this good post.

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2012-04-12 14:08 by abercrombie fitch
Buen trabajo, siempre disfruto leyendo tus cosas

# re: [译]Google C++编程风格指南(二)  回复  更多评论   

2012-07-02 06:41 by buy an essay online
View this home page if you wish to purchase essays from the recommended organisation. You will definitely be satisfied with perfect essays writing.

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理