C/C++之冲突和共处

C没有抽象数据类型的能力,C++支持ADT,同时支持OO,而且还是多继承的OO,同时支持接口继承和实现继承。

所以引出一大堆问题和冲突。

其中最主要的是关于初始化的问题。

我们知道,C/C++严格区分初始化和赋值,很多人觉得挺奇怪,初始化不就是初次赋值么?呵呵,似乎就是,又似乎不是。初始化是在定义的时候赋值。

那位说了,这有啥好处?这涉及到一个程序状态正确性的说明性方法的问题。具体的说:就是涉及到断言的问题。

断言一般分为三种,静态断言、动态断言和不变性断言。所谓静态断言就是论断静态情况下成立的那种断言,初始化就是明显的静态行为。动态断言就是论断程序动态行为中符合的断言,典型的例子就是Eiffel的前置条件和后置条件或者叫做前提和结论。不变性断言是更高层次的断言,它论断程序永远遵从的限制,规定出程序的本质特征,对应于Eiffel的不变式。

其实初始化就是一个静态断言,表明该对象的值静态的等于这个静态初始化表达式的值。

C语言虽然不支持ADT,但是它支持Compound Data和数组,所以它的初始化方法也是比较复杂的。有兴趣的读者可以看看我的另一篇关于 = 0的blog里面涉及到C语言的初始化和组合字面值等问题。

C的初始化的基本语法举例如下:

int i = 6;
struct S
{
int a;
short b;
};
struct S o = {.a = 3, .b = 4};
...
另外还有数组,我就不举例了。

C++当然也可以用这些方法(其实现在似乎不能用,不过我相信以后会能用的),但是,C++又提供了一个更一致和抽象的方法——构造函数。

构造函数的语法如下:

class C
{
public:
C(int i, short s)
: _i(i)
, _s(s)
{}
private:
int _i;
short _s;
};

很多人批评他奇怪的语法,问为什么不像不同的方法一样写在{}里面,对于这个,我的想法是:由于这是一个静态断言,而不是一个赋值运算,所以这个特定的语法是合适的。

对于初始化,语法是这样的:

C o(3, 5);

当然了,也有人会这样写:

C o = C::C(3, 5);

这估计是为了照顾情绪低落的C程序员,主要是为了一个习惯,其实两者是一样的。

T o(initializeExpr)这种语法强烈的影响了C++的文化,甚至连原始类型都可以这样初始化了。

比如:

int i(0);

你可以认为int也是一种类型,它也有一个构造函数,甚至都可以有默认值……

这个统一看起来是小事一桩,其实对于template大有用处。而且还有更深层次的语义改变,你能看出来么?

我直说了,不管怎样T o = xxx这种语法都是不可重用的,你如果想规定第二个o也等于xxx你就得另写一遍或者使用赋值运算符,而如果你想给出一个稍有一点差别的但是基本规则相同的值,你用=语法就没有办法了。

而构造函数导致的T o(xxx)这个语法,使得你可以重用构造规定的一系列静态断言和赋值规则(顺便说一句,int i()保证i为0,这就是一种重用),第一种语法没有这个重用性。

C++的麻烦在于它有两种初始化的语法和语义,这会导致语言复杂,编译器复杂,最主要的是导致程序员迷惑,这是生产率的大敌。

不说了,赶快回家吃饭吧。

根据上面说的东西,大家一定会认为我赞成构造函数而反对复合字面常量,其实不是这样的。两者各有用处,相对来说,构造函数这种方式比较重量一些,复合字面常量轻量一些,联系现在流行的敏捷开发,现在流行的脚本式语言,我们可以感觉出来轻量级方法的优势。
VSCode右上角运行按钮神秘消失?别慌,先检查C/C++插件的IntelliSense Engine设置 本文深入解析VSCode中C/C++插件配置冲突导致运行按钮消失的问题,重点排查IntelliSense Engine设置冲突。提供从现象诊断到根治方案的完整指南,包括配置同步策略和防御性编程实践,帮助开发者高效解决这一常见问题。 阅读详情

相关推荐

解决C++项目中TBB、Qt与MSVC编译冲突:emit与min/max宏问题实战指南

在C++跨平台开发中,预处理器宏和命名冲突是常见的编译难题,尤其在集成多个第三方库时。这类问题通常源于不同库对C++标准或关键字的差异化处理,导致代码在预处理阶段被意外展开或替换。其技术价值在于,理解并解决这些冲突是构建稳定、可维护大型项目的基石,直接影响编译成功率和团队协作效率。应用场景广泛,涵盖高性能计算、图形界面开发、游戏引擎及桌面应用等领域,其中集成Intel TBB进行并行计算与使用Qt框架构建GUI是典型组合。本文聚焦于该组合在Windows MSVC环境下最突出的两个编译冲突:因Windows

weixin_30480075的博客 322

C++多继承 基类命名冲突

多继承中的二义性问题 在派生类中对基类成员的访问应该是唯一的。但是,在多继承情况下,可能造成对基类中某个成员的访问出现了不唯一的情况,这时就称对基类成员的访问产生了二义性。 class base1 { public: void fun(); }; class base2 { public: void fun(); }; class derived:public base1,public base2{}; int main() { derived obj; obj.fun(); ...

q610098308的专栏 1304

KeilC51和MDK同时安装后编译冲突解决方案:实践型指南

在keilc51和mdk同时安装的环境下,编译时常出现路径混淆与工具链冲突。通过调整环境变量优先级、分离安装路径和指定独立编译器,可有效解决keilc51和mdk同时安装带来的问题,确保双环境稳定运行。

weixin_28922227的博客 866

【C++问题集锦——持续更新中】

C++问题集锦

保持分享欲 962

Windows下Rust与C/C++混合开发:WinLibs GCC 15 + CMake 4环境配置指南

在跨平台软件开发中,Rust与C/C++的混合编程是常见需求,通过FFI(外部函数接口)实现语言间互操作。其核心原理是利用统一的ABI(应用程序二进制接口)和链接机制,使不同编译器生成的代码能够协同工作。这种技术价值在于能复用庞大的C/C++生态库,同时享受Rust的内存安全特性。在Windows平台上,由于缺乏原生GNU工具链,配置兼容的构建环境成为关键挑战。本文聚焦于使用WinLibs提供的GCC 15与CMake 4组合,该方案集成了现代MinGW-w64工具链,解决了链接器兼容性和C++标准库版本冲

weixin_30321449的博客 386

C++命名空间详解:从语法到工程实践,解决名字冲突与代码组织

在C++编程中,命名空间是解决名字冲突、组织大型代码库的核心机制。其原理是通过作用域封装,将标识符分组管理,避免不同库或模块间的符号污染。这一特性对于提升代码可维护性和复用性至关重要,尤其在引入第三方库或团队协作时。从基础语法如namespace定义、using声明与指令,到嵌套与匿名命名空间,再到工程中的高级应用如头文件保护、内联命名空间版本管理,命名空间贯穿了现代C++工程实践。通过合理使用命名空间,开发者能构建清晰、模块化的代码结构,有效管理依赖,并利用ADL等特性实现优雅的接口设计。本文结合具体示例

weixin_32715349的博客 231

多个c/c++动态库函数同名冲突解决方法

最近某个程序需要调用多个动态库,但是不同的动态库中使用了功能不同的同名函数,导致调用出现偏差,可参考以下解决办法。 样例 假设有动态库libFuncA.so和libFuncB.so,他们的内部实现分别为: /*func_A.c*/ #include<stdio.h> //内部函数 int sayHi() { printf("Hi,this is AAAAA\n"); return 0; } //外部调用函数 int sayOut() { sayHi();

woniuye的博客 7706

数据清洗(Data Cleansing)

数据清洗(Data Cleansing)是指对数据进行处理和纠错,以去除或修复数据集中存在的错误、不致、不完整和冗余的数据,从而使数据更加准确、可靠和有用。数据清洗是数据处理和数据分析中一个非常重要的步骤,它可以帮助我们提高数据的质量,从而提高数据分析和机器学习的准确性和可靠性。数据清洗是一个重要的过程,它可以帮助我们提高数据的质量,从而提高数据分析和机器学习的准确性和可靠性。在实际应用中,我们可以使用一些工具和技术来实现数据清洗,例如 Pandas、NumPy 和 OpenRefine 等。通过数据清洗,

meimei169500的博客 1万+

【C++】内部类(解决名字冲突问题一)

将内部类看成普通成员,符合普通成员的规则,用法就是正常类的使用方法。 定义内部类 把一个类的定义写在另一个类的内部,则成里面的这个类为内部类。例如,下面代码中的Inner类 #include &lt;stdio.h&gt; #include &lt;string.h&gt; class Test { public: class Inner { public: ...

mjiansun的专栏 1580

微信小程序转化数据API自归因实战:PHP实现与2025升级要点解析

本文详细解析了2025年微信小程序转化数据API自归因的升级要点与PHP实战实现。核心变化包括接口地址更新、固定access_token的获取方式,以及新增timestamp与nonce等安全参数。文章提供了完整的PHP代码示例,帮助开发者高效完成数据上报,优化腾讯广告投放效果。

git9versioner的博客 989

Eclipse在Mac上报错JNI_CreateJavaVM?可能是你的JDK架构搞错了(附Adoptium JDK下载指南)

本文深入解析了Mac(尤其是Apple Silicon芯片)上Eclipse启动时出现“JNI_CreateJavaVM”错误的根本原因,即JDK架构(aarch64与x86_64)不匹配。文章提供了详细的诊断步骤,并推荐通过下载并配置Eclipse Adoptium提供的aarch64版本JDK来彻底解决问题,同时附上清晰的配置指南。

weixin_29065659的博客 321

C++初阶01——用命名空间避免同名冲突

所谓命名空间,实际上就是一个由程序设计者命名的内存区域。程序设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。如int a;double b;namespace是定义命名空间所必须写的关键字,ns1是用户自己指定的命名空间的名字,在花括号内是声明块,在其中声明的实体称为命名空间的成员。现在命名空间ns1的成员包括变量a和b,注意a和b仍然是全局变量,仅仅是把它们放在命名空间而已。

2302_77683642的博客 2104

Potplayer + LAVFilters + madVR 配置教程

文章目录Potplayer + LAVFilters + madVR 配置教程工具安装篇设置调教1.potplayer播放器设置加载LAVFilters和madVR1.选择“源滤镜/分离器”选项,选择“滤镜/解码器管理”2.“添加外部滤镜”3.浏览到刚才LAVFilters解压的文件夹,分别添加图示项。4.添加后回到管理界面设置,点击左边的”LAV AudioDecoder”,将右边”音频解码器”...

re 16万+

VSCode配置C/C++和clangd后,运行按钮时有时无?可能是setting.json在‘捣鬼’

本文深入解析VSCode中同时使用C/C++插件和clangd时运行按钮异常的问题,揭示setting.json配置冲突的本质。通过系统化诊断流程和配置清理方案,帮助开发者解决IntelliSense引擎与clangd的兼容性问题,恢复稳定的调试功能。

culing2941的博客 1106

数据去重复_京东商品评论情感分析|文本数据预处理

本文爬取了十款热销手机的文本评论数据后,首先对文本评论数据做文本预处理,文本评论数据中存在大量的无价值信息,引入无用的文本数据,对其作情感分析,显然没有价值,得出的文本挖掘结果也不尽人意。所以对于文本评论数据先进行文本预处理是必不可少的一步,把大量的、冗余的、无价值的信息去除,可以极大提高文本数据的质量,精确文本分析结果。1 文本去重1.1文本去重的原因文本数据预处理时,首先应去除文本评论数据中反...

weixin_34556808的博客 2074

一文带你了解什么是RDMA

RDMA(Remote Direct Memory Access,远程直接内存访问)是一种起源于高性能计算领域的通信技术,如今已广泛应用于数据中心。该技术使得用户程序能够绕过操作系统内核及CPU,直接与网络接口卡(NIC)交互,实现网络通信。这种方式不仅大幅提升了通信带宽,还显著降低了网络延迟,优化了整体性能。

嵌入式技术开发 6016

Visual Studio中C/C++混合编程配置与extern “C“使用详解

在软件开发中,混合编程是一种常见的技术实践,它允许不同编程语言编写的模块在同一项目中协同工作。其核心原理在于解决不同编译器间的符号命名与链接规范差异,例如C++的名字修饰与C的简单符号命名规则。这种技术的价值在于能够充分利用现有成熟的C语言生态库,同时结合C++的现代特性进行高效开发。在实际应用场景中,常见于集成历史遗留的C语言库、调用硬件设备的C接口驱动,或在大型项目中实现模块化分工。通过使用extern "C"链接规范,可以明确告知C++编译器对特定代码段采用C语言的链接规则,从而避免链接错误。本文以V

weixin_30600197的博客 512

SOUL.md 人格定制的 7 个高阶技巧:Hermes Agent 精准控制 AI 行为模式

揭示 SOUL.md 的本质是行为契约而非人格设定,介绍7个围绕边界约束的高阶技巧,包括用上下文锚点(INPUT SCOPE/OUTPUT TARGET/CONSTRAINTS)替代角色描述、动态渲染锚点适配CI流程等,显著降低token消耗与人工review耗时。

weixin_42520239的博客 252

C++项目构建实战:解决raylib与cURL库冲突的完整指南

在C++项目开发中,库依赖冲突是常见的技术挑战,尤其在涉及图形渲染与网络通信的跨领域应用中。其核心原理在于不同库可能依赖冲突的底层运行时库(如C标准库、OpenSSL)或全局符号,导致链接阶段的“多重定义”错误或运行时崩溃。从技术价值看,理解并解决这类冲突能提升对构建系统、链接模型及二进制兼容性的掌握,是进阶工程实践的必备技能。应用场景广泛覆盖游戏开发、图形工具、嵌入式系统及高性能应用集成。本文聚焦于raylib图形库与cURL网络库的集成冲突,通过源码编译统一环境、动态链接隔离、包管理器自动化等方案,提供

weixin_34005090的博客 250

非技术面试题精选大全

回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有,其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理企业才会相信。企业喜欢有礼貌的求职者。

吃面爱放香菜的博客 435

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

从编码战争到和平共处:C++开发者如何驾驭UTF-8与GBK的江湖恩怨

本文探讨了C++开发中UTF-8与GBK编码冲突的解决方案,特别针对Windows环境下中文输出乱码和编译报错问题。通过分析编码差异本质,提供了VSCode、CLion及命令行环境下的实用配置指南,帮助开发者实现跨平台编码兼容,提升开发效率。

z4a5b6的博客 178

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C++命名空间 vs 动态库符号冲突:你的代码真的安全吗?

本文深入探讨了C++命名空间在大型项目中的局限性,揭示了动态库链接时因符号冲突引发的潜在风险。文章重点分析了链接器处理重复符号的优先级规则,并提供了通过控制符号可见性、使用版本脚本和依赖隔离等策略,构建真正健壮的C++二进制接口(ABI)安全防线。

weixin_29002595的博客 223

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C/C++语言程序设计进阶与数据结构(一)

本文系统介绍了C语言中的关键字、标识符、变量、数据类型、常量、输入输出函数及进制转换等基础知识。关键字是C语言赋予特殊含义的字符串(如if、int),全部为小写字母。标识符用于命名变量、函数等,需遵循特定命名规则。变量是内存中的存储单元,需先声明后使用,具有特定数据类型和作用域。数据类型包括整数、浮点、字符等类型,各有不同存储空间和取值范围。常量分为字面常量、宏定义常量、const常量和枚举常量。输入输出函数如scanf()、printf()等用于数据传输。最后讲解了二进制、八进制、十进制和十六进制

2302_78675318的博客 836

Visual C++运行库缺失与冲突的完整修复指南:从诊断到彻底解决

动态链接库(DLL)是Windows系统中实现代码复用和模块化的重要机制,其原理在于程序运行时从共享库中加载所需函数,从而减少冗余并便于更新。这项技术的核心价值在于为开发者提供了统一的运行时环境,确保用不同版本Visual Studio编译的应用程序能在用户系统上稳定运行。在实际应用场景中,许多专业软件和大型游戏都依赖特定版本的Microsoft Visual C++ Redistributable Package(即VC++运行库)来提供必要的C++标准库和运行时组件。当这些运行库文件缺失、版本不匹配或发

weixin_30654583的博客 356

C++入门基础

最近5年里,编程语言的发展可谓是进入了井喷时期,每年都会诞生超过50多种新的编程语言,但是C++语言始终在编程语言排行榜中位居前三,还不时地挑战榜首。由此可见C++的含金量了,但是它的学习难度也很大,但是我们不要害怕,正如翁恺老师所说的:“计算机的所有东西都是人做出来的,别人能想出来的,我也一定能够想出来,在计算机里没有任何黑魔法,所有的东西只不过是我现在不知道而已。总有一天,我会把所有细节,所有内部的东西全都搞明白。

H2X7_的博客 768

BrewUI ANSI 解析器详解:如何为 Homebrew 命令输出着色(完整指南)

BrewUI 是 Homebrew 官方推出的 macOS 图形界面(GUI),让不熟悉终端的用户也能图形化地安装、更新和管理 Homebrew 软件包。而它的控制台之所以能像原生终端一样显示彩色输出(蓝色 `==>`、绿色下载进度、红色报错),全靠一个轻量级组件——ANSI 解析器(ANSI Parser)。本文带你从零看懂它的工作原理、设计取舍,以及它在 BrewUI 中如何一步步把原始字节渲

gitblog_00605的博客 457
上一篇: C++缺陷之作用域运算符::
下一篇: 类型,转换,数组,协变及其他
lifeNet
博客等级 码龄20年 1粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值