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++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的