IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 程序猿的口味-从C++STL聊到MSYS2-Qt -> 正文阅读

[C++知识库]程序猿的口味-从C++STL聊到MSYS2-Qt

一直以来,我在教授C++语言编程课程的时候,总是在泛型上慌得很,生怕自己的半吊子C++知识贻笑大方。还好我发现同学们和我一样都是糊涂虫,只满足于把STL的容器和算法当作简单类型用就完了。印象深刻的一次尴尬就是学生问我:丁老师,怎么你给的例子的链表,和std::list的链表差别这么大,学了泛型,怎么还是看不懂STL库的代码呢?

我只能说,师傅领进门,修行靠个人,我也不懂哩!其实老师眼都看花了,也是看不懂。最近终于看完了,更觉得头大。通过20年的教学,悲哀的发现一个事实,** 哪怕学完一本教材,让我实现一个链表或者字典,也绝对不会长得像STL库 **。每次试着研究STL库、BOOST库的源码,总是觉得在鞭挞我的灵魂,PUA我,让我知道我只是一个C语言学了一半的三流本科野路子。这种情况让我痛不欲生,直到看到了Qt的源码,才重新心情好起来:原来Qt的源码风格非常适合我的口味,每次一打开,我受伤的灵魂就得到了安慰。

Qt实现可读性好

对于这种泛型库,都是没有CPP的,也就是在头文件里直接引入所有代码。可以认为是内联的。但哪怕只有.h文件,可读性也有不同。

文本排版

虽然对头文件来说,ALLinOne可以不管排版,但一般来说,我们实现一个类,还是喜欢不把实现直接写在类的声明里。这样会显著分散接口的文本描述,让维护者不知道这个类有多少方法。STL库大部分方法是直接写在A的声明里:

class A{
//...
	FunA()
	{
		//50行
	}
	FunB()
	{
		//50行
	}
	//...
}

Qt把比较冗长的方法的声明、实现分开陈述。

class A{
//...
	FunA();
	FunB();
		//...
}
A::FunA();
{
	//50行
}
A::FunB()
{
	//50行
}

Qt这样做的好处是,这个类的全貌尽收眼底。就像是你写论文的时候,有个目录,而不是上来就第一段。STL库这样写,2000多行的程序,上来就把人打蒙了。

此外,Qt的缩进、大括号的配对都比较美观。相对起来g++的STL就随意多了。

命名风格

二者的命名风格大不相同。就拿 list::push_front来看
STL:

     void
      push_front(const value_type& __x)
      { this->_M_insert(begin(), __x); }
      // Inserts new element at position given and with value given.
#if __cplusplus < 201103L
      void
      _M_insert(iterator __position, const value_type& __x)
      {
	_Node* __tmp = _M_create_node(__x);
	__tmp->_M_hook(__position._M_node);
	this->_M_inc_size(1);
      }
#else
     template<typename... _Args>
       void
       _M_insert(iterator __position, _Args&&... __args)
       {
	 _Node* __tmp = _M_create_node(std::forward<_Args>(__args)...);
	 __tmp->_M_hook(__position._M_node);
	 this->_M_inc_size(1);
       }
#endif


#endif

Qt:

inline void push_front(const T &t) { prepend(t); }
template <typename T>
inline void QList<T>::prepend(const T &t)
{
    if (d->ref.isShared()) {
        Node *n = detach_helper_grow(0, 1);
        QT_TRY {
            node_construct(n, t);
        } QT_CATCH(...) {
            ++d->begin;
            QT_RETHROW;
        }
    } else {
        if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
            Node *n = reinterpret_cast<Node *>(p.prepend());
            QT_TRY {
                node_construct(n, t);
            } QT_CATCH(...) {
                ++d->begin;
                QT_RETHROW;
            }
        } else {
            Node *n, copy;
            node_construct(&copy, t); // t might be a reference to an object in the array
            QT_TRY {
                n = reinterpret_cast<Node *>(p.prepend());;
            } QT_CATCH(...) {
                node_destruct(&copy);
                QT_RETHROW;
            }
            *n = copy;
        }
    }
}

STL库的变量名,太多的下划线(__)和奇怪的前缀,比如_M_, 可读性太差。namespace是可以嵌套的,既然这么怕重名,还不如定义namespace呢。

其实Qt吸引我的远不止上述这些,我在开发工具上的个人口味,决定了我在用Windows开发时,只爱 MSYS2, 以及里面的Qt。

个人口味

我一直觉得自己水平很差,还敢教学生写代码。唉,真的惭愧。不过我发现可能我这样水平的人,真的不适合学习纯粹的C++、不适合学Java,不适合学Python,不适合学C#,还是学习Qt吧。没办法,写了这么多年程序,从Logo语言(中华学习机)、GWBasic, Qbasic, VisualBasic, TC2.0, TC3.1, Borland C++/BCB,VC/MFC 到 GNU C++, Java, Python,node.js, plpgSql, plsql , Excel 以及VBScript, bash,……需要啥子,就学啥子,但是不代表我都喜欢——有些东西,我一直难以习惯,即使看得懂,也很难喜欢——不合口味。

讨厌的口味

  1. 下划线、非字母开始的变量 :如Bash的 $(),以及STL实现里的__xxx
  2. 全大写的东西 : 老式Basic语言, 很多公司建立的SQLServer, Oracle模型。
  3. 超过两层或者10个字符的引用: Java的一堆包.Axxx.Byyyyy…,C#的System.Math.XXXXX,以及 boost/ C++20 的 std::chrono::system_clock::now
  4. 把实现直接写在Class里: Java、C#, STL都这样干。
  5. 弱类型语言: 在竞赛时,曾经因为把 backaside 变量在某处误写为 backside,结果程序不报错,痛失冠军。从此抛弃任何不需要显式定义变量的语言。
  6. 发布时需要另外携带解释器、虚拟机、子安装包:Python, Java(jvm),C#(clr), Basic, Node.js, Matlab,vcredist等等。
  7. 发布、运行时要使用注册表、环境变量:注册表一堆东西,而后在环境变量配置一堆东西。
  8. 运行时文件夹文件太多,又小又碎:把程序发布给终端用户,还要携带大量html,png,资源,携带大量脚本。一个文件夹里上万个文件(人家是要使用,不是开发)。
  9. 深埋文件夹:把自己安装在user/UserName/appData/…下,并在Local里有好多垃圾文件。
  10. C++库、COM/OLE、.Net:一定是C的库,C的库是最简单,兼容性最高的。哪怕用C++,用Qt,都要导出C接口的库,而不是C++的。
  11. 文本接口: JSON和XML可读性好,但是解释这些东西很浪费时间。宁可解决大小端、二进制兼容性问题,也不想为了解释文本引入第三方库。
  12. 非原生IDE:IDE应该一开始就是为了核心工具链研发的,而不是万精油的。哪怕我喜欢Qt,也尽量避免在VS里使用Qt。

喜欢MSys2Qt的原因

  1. 开发环境无污染:msys2是文件夹封闭的,在线安装后,重装系统了,直接释放原来的备份压缩包,一切如初。
  2. 发布环境无污染:msys2 Qt的依赖是封闭的,发布时,直接放在文件夹里,拷贝齐了动态库,就不用要求用户安装任何东西。对比起来,msvc Qt可能需要安装VC运行时。重要的是文件夹里放的东西不是很碎。
  3. 开源、跨平台:存粹喜欢开源。现在犯了强迫症,自己写的代码总是要在x86,x64,arm,arm64上编译,都能用了才开心。用MSYS2 Qt,基本很省心。
  4. 库较为完整:在windows下,基本上常见的Linux C库都有实现,且不用配置。MSYS2就是一个完整的小bash环境。
  5. 效率高:与Cygwin相比,用的是Mingw,没有API转接,效率很高。
  6. API优雅 Qt的API非常优雅,一致性很高。
  7. 文档优雅 我觉得,看过的文档里,MSDN、Archlinux、Qt、PostgreSQL这四个东西的文档给我的印象很好,除了MSDN,其他三个和MSYS2都有交集。
  8. 源码优雅 源码我看得懂!不PUA我,不鄙视我。

总观点

MSYS2 + Qt是给一个一般水平的科研工作者开发出工业级别生产力工具的极佳解决方案。不需要很多的投入,就可以开发出跨平台的、绿色版的高度可用的生产力工具。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:30:29  更:2022-03-21 20:31:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:12:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码