C专家编程 第11章 你懂得C,所以C++不再话下 11.19 它或许过于复杂,但却是唯一可行的方案

编程入门 行业动态 更新时间:2024-10-28 04:28:26

C专家编程 第11章 你懂得C,所以C++不再话下 11.19 它或许过于复杂,<a href=https://www.elefans.com/category/jswz/34/1709830.html style=但却是唯一可行的方案"/>

C专家编程 第11章 你懂得C,所以C++不再话下 11.19 它或许过于复杂,但却是唯一可行的方案

    它或许过于复杂,但却是唯一可行的方案
    C语言原先的设计哲学“所有的特性都不需要隐式的运行时支持”已经做了一定的妥协。

    C++对C语言的改进
    *在C语言中,初始化一个字符数组的方式很容易产生这样一个错误,即数组很可能没有足够的空间存放结尾的NUL字符。C++对此作了一些改进,像char b[3] = "Bob"这样的表达式被认为是一个错误,但它在C语言中却是合法的。
    *类型转换既可以写成像float(i)这样看上去更顺眼的形式,也可以写成像(float)i这样稍显怪异的C语言风格的形式。
    *C++允许一个常量整型来定义数组的大小:
    const int size = 128;
    char a[size];
    这在C++中是允许的,但在C语言中却是错误的。
    *声明可以穿插于语句之间。在C语言中,一个语句块中所有声明都必须放在所有语句的前面。C++去掉了这个专横的限制,做得非常好。既然这种做法也会引起与C语言的不兼容,那为什么不进行的彻底一些,为C语言声明语法提供一种更简单的替代方案呢?

    从C转换到C++
    学习C++最好的方式就是从它的ANSI C子集开始编程。把C语言作为一种可移植的机器语言事实上会使链接和调试复杂化。名字混合并不可靠,它会带来可怕的危险,并长期存在于C++中。名字混合是一种在不同的文件间进行类型检查的权宜之策,但它暗示你所有的C++代码必须用同一个编译器编译,因为名字混合策略在不同的编译器上可能各不相同。对于C++的复用类型而言,这是一个巨大的缺陷,因为它有效地防止了二进制一级的复用。
    这里有一个代表性的例子,说明了C语言并非C++的子集,并提示何处可能隐藏着麻烦。
    在C++中存在,但在C语言中却不存在的限制有:
    *在C++中,用户代码不能调用main()函数,但在C语言中却是允许的(不过这种情况极为罕见);
    *完整的函数原型声明在C++中是必须的,但在C语言中却没这么严格;
    *在C++中,有typedef定义的名字不能与已有的结构标签冲突,但在C语言中却是允许的(它们分属不同的名字空间);

    /*
    ** distinction of typedef in c and c++. 
    */
    /*
    ** typdef_struct_label.cpp.   
    */
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct struct_a{
        int a;
    } struct_a;

    int main( void ){

        return EXIT_SUCCESS;
    }

输出:

    /*
    ** typdef_struct_label.c.
    */
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct struct_a{
        int a;
    } struct_a;

    int main( void ){

        return EXIT_SUCCESS;
    }
输出:

     *当void*指针赋值给另一个类型的指针时,C++规定必须进行强制类型转换,但在C语言中却无必要。
    在C++和C语言中具有不同含义的特性有下面这些。
    *C++至少增加了十几个关键字。这些关键字在C语言中可以作为标识符使用,但如果这样做了,用C++编译器编译这些代码时就会产生错误信息。
    *在C++中,声明可以出现在语句可以出现的任何地方。在C语言中的代码块中,所有的声明必须出现在所有语句的前面。
    *在C++中,一个内层作用域的结构名将会隐藏外层空间中相同的文件名。在C语言中,则非如此。
    *在C++中,字符常量的类型是char,但在C语言中,它们的类型是int。也就是说,在C++中,sizeof('a')的结果是1,而在C语言中,它的值要大些。
    *由于C++增加了新的//注释符,因此有时会在两种语言中产生微妙而怪异的差别。 

    protected abstract virtual base pure virtual private destructor是什么
    上面这句话可以分为两个部分:从一个protected abstract virtual base派生而来的pure virtual          private destructor
    *private destructor就是一个对象离开其生存范围时所调用的函数。private表示它只能被本类的成员函数或友元(friend)访问。
    *pure virtual函数本身没有代码,但他可以通过继承作为派生类虚拟函数实现的指导准则。
    *pure virtual destructor只有在被派生类覆盖以后才有意义。由于析构函数能够自动进行类缺省的清理工作,如同调用成员或基类的析构函数一样,所以通常并不需要在析构函数的定义中显式地编写任何代码。
    让我们看一下第二部分
    *abstract virtual base表示基类是被多个多重继承的类所共享(它是虚基类),它至少包含一个纯虚函数(pure virtual function),其他的类通过继承从它派生(所谓抽象基类)。虚基类也有特殊的初始化语义。
    *protected abstract virtual base类是指我们我们的类是以protected形式派生的。该类的后续派生类可以访问父类的信息,但其他的类则不允许。
    现在,把它们放在一起,一个protected abstract virtual base pure virtual private destructor就是一个析构函数,它具有下列特点:
    *只能被该类的成员函数或友元调用
    *在声明它的基类中没有定义,但它将在派生类中定义;
    *它(指派生类)共享一个多重继承的基类;
    *它(指基类)以protected方式继承。
    在C++的代码中,大概可以这样表述:
    class vbc {
        protected: virtual void v() = 0;
        private: virtual ~vbc() = 0;
    }; 
    //vbc是一个抽象类,因为它包含纯虚拟函数
    class X : virtual protected vbc {
        //X虚拟地从继承于vbc,而且vbc的protected成员也是X的protected成员
        //所以vbc是X的protected abstract virtual base类
        protected: void v() {
        } 
        ~X() {
            /*执行一些X类的清理工作*/ 
        }
    }; 
    //当一个X对象被销毁时,X::~X被调用,然后...
    /*X的protected abstract virtual base pure virtual private destructor也被调用,所以尽管它是纯函数,但它仍然需要定义。*/

    /*
    ** inheritance and polymorphism 
    */ 
    #include<stdio.h>
    #include<stdlib.h>

    class vbc {
        protected: virtual void v() = 0;
        /*
        ** [Error] 'vbc::~vbc()' is private
        */
        private: virtual ~vbc() = 0;
    };

    //vbc是一个抽象类,因为它包含纯虚拟函数
    class X : virtual protected vbc {
        //X虚拟地从继承于vbc,而且vbc的protected成员也是X的protected成员
        //所以vbc是X的protected abstract virtual base类
        protected: void v() {
            printf( "v function is called in class X!\n" );
        }
        ~X() /* [Error] within this context */{
            /*执行一些X类的清理工作*/
        }
    };

    int main( void ){
    
        return EXIT_SUCCESS;
    }
输出:/* 你可以试着修改这个程序。例如变动x的析构函数的访问权限。 */

更多推荐

C专家编程 第11章 你懂得C,所以C++不再话下 11.19 它或许过于复杂,但却是唯一可行的方案

本文发布于:2024-03-09 18:03:44,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1725679.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:但却   方案   专家   是唯一

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!