回首页 回首页 ◎ 设为首页  
◎ 收藏本站  
◎ 给我留言  
  
  首 页  C/C++教程  C++之父的FAQ  C/C++动向  C/C++源代码  C/C++误区  Unix/Linux  下载中心  乱七八糟  蚂蚁的Blog  
  当前位置:首 页 >> C++之父的FAQ >> C++ 风格与技术 FAQ >> [转] 为什么我必须把数据放到类的声明之中?
最 近 更 新
[转] 我该把const写在类..
[翻译] 我应该使用按值..
[翻译] 你如何命名变量..
[转] 何种代码布局风格..
[转] “int* p;”和“in..
[翻译] “cout”怎么念?
[转] 宏有什么不好吗?推荐
[翻译] static_cast 有..推荐
[翻译]为何C++里有些东..推荐
[翻译] i++ + i++ 的值..推荐
最 新 推 荐
[转] 宏有什么不好吗?推荐
[翻译] static_cast 有..推荐
[翻译]为何C++里有些东..推荐
[翻译] i++ + i++ 的值..推荐
[翻译] 数组有何不好之..推荐
[转] 为何delete操作不..推荐
[转] 有placement delet..推荐
[翻译] “new”和“mall..推荐
[转] C和C++风格的内存..推荐
[翻译] 为何标准容器效..推荐
热 门 排 行
[转] 我可以写“void ma..
[翻译] 什么是纯虚函数?
[转] 我该把const写在类..
[转] 这个简单的程序…..推荐
[翻译] i++ + i++ 的值..推荐
[转] 我如何从标准输入..
[转] 我怎样才能把整数..
[翻译] static_cast 有..推荐
[转] 宏有什么不好吗?推荐
[转] 我应该怎样处理内..推荐
站 内 搜 索

Web stdcpp.cn
关键词

搜索方式

搜索范围

精确匹配
广 告

[转] 为什么我必须把数据放到类的声明之中?


来源:C++ Style and Technique 作者:Bjarne Stroustrup 翻译:紫云英 等级:一般
发布于2007-05-12 19:56 被读323次 【字体:

Q: 为什么我必须把数据放到类的声明之中?

A: 没人强迫你这么做。如果你不希望界面中有数据,那么就不要把它放在定义界面的类中,放到继承类中好了。参看为何我编译一个程序要花那么多时间条目。[译注:本FAQ中凡原文为declare/declaration的均译为声明;define/definition均译为定义。两者涵义之基本差别参见后面“‘int* p;’和‘int *p;’到底哪个正确条目中的译注。通常而言,我们还是将下面的示例代码称为complex类的定义,而将单单一行“class complex;”称作声明。]
 
但也有的时候你确实需要把数据放到类声明里面,比如下面的复数类的例子:
	template<class Scalar> class complex {
	public:
		complex() : re(0), im(0) { }
		complex(Scalar r) : re(r), im(0) { }
		complex(Scalar r, Scalar i) : re(r), im(i) { }
		// ...

		complex& operator+=(const complex& a)
			{ re+=a.re; im+=a.im; return *this; }
		// ...
	private:
		Scalar re, im;
	};
 
这个complex(复数)类是被设计成像C++内置类型那样使用的,所以数据表示必须出现在声明之中,以便可以建立真正的本地对象(即在堆栈上分配的对象,而非在堆中分配),这同时也确保了简单操作能被正确内联化。“本地对象”和“内联”这两点很重要,因为这样才可以使我们的复数类达到和内置复数类型的语言相当的效率。

[译注:我觉得Bjarne的这段回答有点“逃避问题”之嫌。我想,提问者的真实意图或许是想知道如何用C++将“界面”与“实作”完全分离。不幸的是,C++语言和类机制本身不提供这种方式。我们都知道,类的“界面”部分往往被定义为公有(一般是一些虚函数);“实作”部分则往往定义为保护或私有(包括函数和数据);但无论是“public”段还是“protected”、“private”段都必须出现在类的声明中,随类声明所在的头文件一起提供。想来这就是“为何数据必须放到类声明中”问题的由来吧。为了解决这个问题,我们有个变通的办法:使用Proxy模式(参见《Design Patterns : Elements of Reusable Object-Oriented Software》一书),我们可以将实作部分在proxy类中声明(称为“对象组合”),而不将proxy类的声明暴露给用户。例如:
	class Implementer; // forward declaration
	class Interface {
	public:
		// interface
	private:
		Implementer impl;
	};
在这个例子中,Implementer类就是proxy。在Interface中暴露给用户的只是一个impl对象的“存根”,而无实作内容。Implementer类可以如下声明:
	class Implementer {
public:
// implementation details, including data members
          };

上述代码中的注释处可以存放提问者所说的“数据”,而Implementer的声明代码不需暴露给用户。不过,Proxy模式也不是十全十美的——Interface通过impl指针间接调用实作代码带来了额外的开销。或许读者会说,C++不是有内联机制吗?这个开销能通过内联定义而弥补吧。但别忘了,此处运用Proxy模式的目的就是把“实作”部分隐藏起来,这“隐藏”往往就意味着“实作代码”以链接库中的二进制代码形式存在。目前的C++编译器和链接器能做到既“代码内联”又“二进制隐藏”吗?或许可以。那么Proxy模式又能否和C++的模板机制“合作愉快”呢?(换句话说,如果前面代码中Interface和Implementer的声明均不是class,而是template,又如何呢?)关键在于,编译器对内联和模板的支持之实作是否需要进行源码拷贝,还是可以进行二进制码拷贝。目前而言,C#的泛型支持之实作是在Intermediate Language层面上的,而C++则是源码层面上的。Bjarne给出的复数类声明代码称“数据必须出现在类声明中”也是部分出于这种考虑。呵呵,扯远了……毕竟,这段文字只是FAQ的“译注”而已,此处不作更多探讨,有兴趣的读者可以自己去寻找答案 :O) ]
 

本文乃网上搜集得来,其版权归原作者和原出处所有。如有侵犯版权之处请与我联系,我将马上进行处理。



相关专题:C++ 之父的言论
[转] 我该把const写在类型前面还是后面?
[翻译] 我应该使用按值传递还是按引用传递?

上一篇:[转] 为什么编译要花这么长的时间?
下一篇:[转] 为何成员函数不是默认为虚?

共有评论 0 条 网友评分 1分 查看全部评论

查看全部评论

【发表评论】 评分:1分 2分 3分 4分 5分


验证码:

Powered By Www.Xydw.COM Ver1.14 管理
Copyright © 2005-2006 蚂蚁的 C/C++ 标准编程 All Right Reserved. XCMS
粤ICP备06014124号   站长:Antigloss