C++批判

2024-08-27 20:32
文章标签 c++ 批判

本文主要是介绍C++批判,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.如果能够直接控制构造函数与析构函数,我们不需要右值引用
右值引用有明显的微量机能浪费。移动时必须给指针赋nullptr。然后在析构时的delete里还会有if判定。

C++中,对象的构造与析构不能被以更低级的方式控制。假如有一个类,我们希望它不被构造。但C++规定了,如果一个类没有无能的默认构造函数,则不可能实现我所说的,就是阻止这个 默认内存块进行自动构造。GDI+就有这样的类,就是Gdiplus::Graphics类。这导致其使用起来很难实现效率最优。

所谓机能浪费,就是让计算机做多余的事情。

因此,需要有这样两个关键字:no_construct、no_destruct。前者阻止对象被自动构造。后者阻止对象被析构。
阻止对象自动构造的原因在于,希望在声明之后手动调用构造函数。
阻止对象自动析构的原因在于,保证之后将对象合理转移。
有了这两个东西,就不再需要怪物一样的右值引用了。
右值引用毫无价值,纯粹是一种荒谬的概念。我们需要正义的语言特性。
C++创造性地发明了构造函数和析构函数(当然,这不全是它的功劳),却没有使它们完备。希望新的C++标准能够使这对发明完备。
允许对象暂时不进行构造,手动控制构造函数。
允许对象不自动析构,保证之后对象将被合理转移,或者手动调用析构函数。
void func()
{
  object obj;    //obj未被构造。
  object obj();  //obj执行的是默认构造方法。
  
  no_construct object obj; //相当于“object obj;”。
  no_destruct object obj;
  
  //结尾处,obj将不会被析构。
}

2.模板就不能限定范围吗?

我阅读了本贾尼的书(书名忘了...最近一直在读),里面提到了“概念”这个概念。如果这个特性加入标准,则我下面的论述就毫无意义了。

但是这个概念终究没有加入标准(理由是,会更加严重地降低编译速度)。或许,新标准还是可以考虑类似的事情的。

我们需要这样的模板,能够控制实例化范围。这个范围可以称之为类型区间。因为模板管得太宽所造成的麻烦实在太多太多了。
有时候,举个例子:
有下面这些类型:
A,B,C,D,E,F,G,H,I,J,K,L,M,N
我们希望将一个模板应用到A-D,另一个同名模板应用到E-G,而H,I,J有自己的同名重载函数方法。
以现在的C++模板,这是不可能的。
你只能选择一个最大的范围,定义为模板,而其他的类型,需要特化方法的化,就只能一一重载了。
以后有新的类型,照样要一一重载。这太可恶了。
模板这种东西,本来就和宏差不多。如果我是语言发明者,我会让预处理器去处理模板。
但我不是。假如非得要实现这样的功能,没有很好的办法,只能定义两个或多个名称不同,参数一样的模板,然后通过重载函数的方法,对每个对象进行重载。
这,太麻烦了!我不喜欢这种过程。一一重载即使能使用宏,仍然是无聊乏味的工作。
template<typename T> void A_D_func(const T & r){ ... }
void func(const A & a){ A_D_func(a); }
void func(const B & b){ A_D_func(b); }
void func(const C & c){ A_D_func(c); }
void func(const D & d){ A_D_func(d); }


template<typename T> void E_G_func(const T & r){ ... }
void func(const E & e){ E_G_func(e); }
void func(const F & e){ E_G_func(f); }
void func(const G & g){ E_G_func(g); }


void func(const H & h){ ... }
void func(const I & i){ ... }
void func(const J & j){ ... }
如果有宏,可以这样:
#define MC_FUNC(X) void func(const X & x){ A_D_func(a); }
MC_FUNC(A)
MC_FUNC(B)
MC_FUNC(C)
MC_FUNC(D)
#undef MC_FUNC
我受够了。


我希望这样:
template<typename T(A,B,C,D)> void func(const T & r){ ... }
template<typename T(E,F,G)> void func(const T & r){ ... }
以上两个模板对实例化的范围进行了限定。第一个只对A,B,C进行实例化。第二个只对E,F,G进行实例化。
只有被用到的函数才真正被实例化,并非列表中出现的类型都会被实例化。
省去了好多麻烦。有多少时间浪费在了这么无聊的事情上呢?
3.我希望在已存在的类中添加方法
一旦一个类已经写就,就不可能往里面增添方法了。
比方说:
class C
{
   using me = C;
   me(){}
   me(int){}
   me(int,const word * s){}   //using word = wchar_t;
   void func(){}
};
我希望往C里面添加一个函数:
   void func2(){}
除非修改源代码,否则绝不可能往类里添加方法。
而很多既有的库的类都是已经封装好的。你总不能直接往那里面添加东西。这当然不行。
因此,可能还能使用一个技巧——继承。
而继承太麻烦了。继承最大的缺点是:不能继承构造函数!
构造函数是不能继承的,即使我只想在其上添加几个非常普通的方法函数。
我也不得不自己手写构造接口!
class CC:C
{
   me(){}
   me(int i):base(i){}
   me(int i,const word * s):base(i,s){}
   void func2(){}
}
我一头撞死算了!第3,4,5行一点意义都没有!这应该由编译器自动完成!
要实现这一点,要么增加关键字,要么定个规则。如果没有添加其他的数据成员,将自动继承基类构造函数。
后者比较现实。因此:
class CC:C{}
将自动继承基类的构造方法。然后我们就可以直接添加方法了。也是比较方便的。
但是,我还是希望能够在类的外部添加成员方法,哪怕其实际的调用方式与原生方法不太相同。
void CC:.func3(){ ... } //是的,新的符号:“:.”。
要调用func3,需要这样调用:
CC cc;
cc:.func3()
或许,可以统一定义外附类方法。外附类方法是以模板实现的。具体细节以后详细讲。
总之,我非常希望能够自行扩充现有类。
如果要求外接成员函数这样调用:
cc.func3(),必须考虑名字碰撞的问题。旧的类方法是不允许覆盖的。如果允许会产生很多问题。
因此扩展方法仅仅只有在名字未被使用的情况下才允许。
4.假如能够实现自定义语法
C++没有一个更好的预编译器。其宏与C语言几乎完全一样。这非常让人失望。我们需要一个更先进和强大的预编译器,以至于甚至连自定义语法的功能都能通过预编译器实现。
最好这个预编译器甚至能够控制符号的文本显示格式,比方说,字体的颜色,风格。
我想多了。这样的东西令人向往,然而或许不是C++追求的目标...

这篇关于C++批判的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112707

相关文章

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

2024/9/8 c++ smart

1.通过自己编写的class来实现unique_ptr指针的功能 #include <iostream> using namespace std; template<class T> class unique_ptr { public:         //无参构造函数         unique_ptr();         //有参构造函数         unique_ptr(