作者cppOrz (cppOrz)
看板C_and_CPP
标题Re: [问题] C++ 不能像 Java 一样,完全避掉 pointe …
时间Sat Nov 26 05:13:50 2005
※ 引述《eliang ()》之铭言:
: 我自己在写程式的时候, 对於 reference 和 pointer 的选择方式是:
: 「尽量使用 reference, 不能用 reference 时才用 pointer」
这是个好习惯。不过个人的建议是,在 C++ 中,最好是把两者都当作
基本语汇,不要刻意去避免而扭曲语法,自然就好。
举个例子:
X *p = new X;
你也可以写成
X &r = *new X;
但後者并没有什麽好处。
: 可是这样会造成整体不一致, 因为有地方用 reference, 有地方用 pointer,
: 写程式时常常会搞不清楚当初宣告的型别是什麽, 而要回头去查前面的程式码,
一些 IDE 或编程环境可以辅助这个问题,不过「回头查」并没有麻烦到哪里去。
以介面设计来说,传递(参数或回传值)reference 或 pointer 的取舍,主要
考量在於其值是否可能为 Null,如果有可能为 Null 就用 pointer,反之则用
reference,例如:
struct C1
{
C1(X const * =0); // 建立 C1 物件可要可不要某个 pointer to X 物件
...
};
struct C2
{
C2(Y const &); // 建立 C2 物件必须参照某个 Y 物件
...
};
X *fooX(); // fooX 可能回传空值
Y &fooY(); // fooY 回传某个 reference to Y 物件
: 想学 Java 完全都使用 reference 也不行, 因为以下用法都不合法:
: int& a[10]; // 10 个 int 的 reference, 可以分别参考 10 个 int
: vector<int&> b; // 元素为 int& 的动态阵列
: 结论是:
: reference 和 pointer 混用 -> 一致性差, 造成写程式不方便
: 完全使用 reference -> 行不通
: 那麽是不是乾脆一律用 pointer 还比较好?
: 请问大家是怎麽选择的?
有两点应该要澄清。
首先,reference 和 pointer 不仅在语法上和语意上有所不同(主要差别在
於 pointer 带有变量的特性),例如前面的例子,所以何来「一致性差」的
问题?大约只能说,reference 在某些情况下可以取代 pointer,而当两者都
适用时,reference 的语意范围较窄,且在语法上比较简洁,因而在此情况下
「尽量用 reference」是好习惯。
(X & 的语意近似 X * const,也就是舍弃 pointer 带有变量的特性,且在
建立时,就必须完成初始化的动作;当然细微处仍有不同,例如 X * const
可以接受 0 值让其他模组作检查。语法上则自然以 reference 较简洁。)
其次,C++ reference 和 pointer 的机制,在内部都有额外的配置耗用,所以:
void foo(X);
void foo(X const &);
void foo(X const *);
以上三种写法,如果 X 是某个 sizeof 不大於指标所占空间的基本型别(例如
int),写成後两种并不会比第一种更有效率,所以某些讲求效能的程式库,其
所提供的 template 代码,还会提供静态型别选择的机制,来作为优化(当 X
是基本型别用第一种,否则用第二种)。
同理,Java 的设计也一样,它针对基本型别,例如 int,和 C++ 一样是采取
「传值」的语意,也就是在参数或回传值传递时,是会自动产生一个复本的。
只有对使用者自订型别,是采取内建式的「reference」语意。(并非如你所谓
的「Java 完全使用 reference」)
所以,假如 X 的型别是 int 的话,写 vector<X &> 不如直接写成 vector<X>
,後者不但简洁,执行效率还比较快。
当然 vector<X&> 是错的,当 X 不是基本型别时,为了效率考量,在 C++ 中
一般是用 vector<X*> 来取代;或者透过一个代理类别:
class X { ... };
typedef boost::shared_ptr<X> XRef;
接下来使用 vector<XRef>,就和 Java 的惯用法差不多了。
至於 Array,也是透过一个代理容器:
boost::shared_array<X> Array(new X[n]);
好处是在多数场合(尤其是 sizeof(X) / sizeof(XRef) 比值不大时),效率上
比 vector<XRef> 占优势。(但 vector 优点在於弹性和延伸性)
但总之,不论 Java 内部是怎麽实现的,也不可能会是:
X &x[n] 或 vector<X &> 这种东西。
C/C++ 遵循「传值」语意,使用 pointer 或 reference 由用户自决;Java 的
reference 语意是内建设施(但不包括基本型别),用户是没得选的。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.120.214.120
※ 编辑: cppOrz 来自: 59.120.214.120 (11/26 05:15)
1F:推 eliang:太感谢了:) 11/26 16:00