荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Second (石开), 信区: Program
标  题: C++语言常见问题解答(1-5,6)建构子和解构子/运算?
发信站: 荔园晨风BBS站 (Wed Sep 19 12:06:21 2001), 转信

=============================
■□ 第5节:建构子和解构子
=============================

Q17:建构子(constructor)是做什麽的?

建构子乃用来从零开始建立物件。

建构子就像个「初始化函数」;它把一堆散乱的位元组成一个活生生的物件。最低限

度它会初始化内部用到的栏位,也可能会配置所须的资源(记忆体、档案、semaphore

、socket 等等)。

"ctor" 是建构子 constructor 最常见的缩写。

========================================

Q18:怎样才能让建构子呼叫另一个同处一室的建构子?

没有办法。

原因是:如果你呼叫另一个建构子,编译器会初始化一个暂时的区域性物件;但并没

有初始化“这个”你想要的物件。你可以用预设参数(default parameter),将两

个建构子合并起来,或是在私有的 "init()" 成员函数中共享它们的程式码。

========================================

Q19:解构子(destructor)是做什麽的?

解构子乃物件之葬礼。

解构子是用来释放该物件所配置到的资源,譬如:Lock 类别可能会锁住一个
semaphore,解构子则用来释放它。最常见的例子是:当建构子用了 "new" 以後,解

构子用 "delete"。

解构子是个「去死吧」的运作行为(method),通常缩写为 "dtor"。


=========================
■□ 第6节:运算子多载
=========================

Q20:运算子多载(operator overloading)是做什麽的?

它可让使用类别的人以直觉来操作之。

运算子多载让 C/C++ 的运算子,能对自订的型态(物件类别)赋予自订的意义。它

们形同是函数呼叫的语法糖衣 (syntactic sugar):

        class Fred {
        public:
          //...
        };

        #if 0
          Fred add(Fred, Fred);         //没有运算子多载

          Fred mul(Fred, Fred);
        #else
          Fred operator+(Fred, Fred);   //有运算子多载
          Fred operator*(Fred, Fred);
        #endif

        Fred f(Fred a, Fred b, Fred c)
        {
          #if 0
            return add(add(mul(a,b), mul(b,c)), mul(c,a));
//没有...
          #else
            return a*b + b*c + c*a;
             //有...
          #endif
        }

========================================

Q21:哪些运算子可以/不能被多载?

大部份都可以被多载。
不能的 C 运算子有 "." 和 "?:"(和以技术上来说,可算是运算子的 "sizeof"
)。
C++ 增加了些自己的运算子,其中除了 "::" 和 ".*". 之外都可以被多载。

底下是个足标(subscript)运算子的例子(它会传回一个参考)。最前面是“不用
”多载的:

        class Array {
        public:
          #if 0
            int& elem(unsigned i) { if (i>99) error(); re
turn data[i]; }
          #else
            int& operator[] (unsigned i) { if (i>99) erro
r(); return data[i]; }
          #endif
        private:
          int data[100];
        };

        main()
        {
          Array a;

          #if 0
            a.elem(10) = 42;
            a.elem(12) += a.elem(13);
          #else
            a[10] = 42;
            a[12] += a[13];
          #endif
        }

========================================

Q22:怎样做一个 "**"「次方」运算子?

无解。

运算子的名称、优先序、结合律以及元数(arity)都被语言所定死了。C++ 里没有

"**" 运算子,所以你无法替类别订做一个它。

还怀疑的话,考虑看看 "x ** y" 和 "x * (*y)",这两者是完全一样的(换句
话说
,编译器会假设 "y" 是个指标)。此外,运算子多载只是函数呼叫的语法糖衣而已

,虽然甜甜的,但本质上并未增加什麽东西。我建议你多载 "pow(base,exponent)"

这个函数(它的倍精确度版本在  中)。

附带一提:operator^ 可以用,但它的优先序及结合律不符「次方」所需。
--
                            既然热爱生命
                            那么,
                            一切都在意料之中。

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.52.239]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店