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

微信小程序使用TCP通信

最终目的:在微信小程序内实现对局域网发起TCP通信实现步骤:建立TCP服务 + 小程序发起通信。

Big_YiFeng的博客 5612

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

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

mjiansun的专栏 1580

AVM环视:系统搭建整体流程

文章目录前言一、畸变矫正鱼眼相机二、透视变换三、图像拼接四、图像融合总结 前言 由于正在做AVM环视,所以记录一下整个过程,归纳为一个系列文章,并对期间遇到的错误进行归纳整理。本文主要概括了AVM环视的大致流程和逻辑,不涉及代码部分,仅供思路参考,其中涉及的具体技术会在后期整理为小章节进行分析。 一、畸变矫正 鱼眼相机 做环视基本上使用到的是鱼眼照片,因为鱼眼相机的视角范围可以达到220°到230°,所以一个相机就可以采集到一个面的全部信息,例如汽车具有四个面,那么在汽车的前后左右分别安装一个鱼眼相机.

qq_34468890的博客 6536

开源项目 ruoyi-sso-oauth2(一)环境配置

Ruoyi若依实现单点登录SSO、oauth2认证

Xiaoweidumpb 9684

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

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

2302_77683642的博客 2104

一分钟理解 “熔断“, “限流“ 与 “降级“

熔断,本质是一种“故障隔离”机制,用于当某个依赖服务出现持续故障(如响应超时、错误率飙升)时,暂时切断对该服务的调用,避免故障扩散到整个系统,防止“雪崩效应”;待依赖服务恢复正常后,再逐步恢复调用。其核心逻辑参考了现实中的“电路保险丝”——电路过载时,保险丝熔断,切断电路,保护电器不被烧毁;故障排除后,更换保险丝,电路恢复正常。闭合状态(Closed):正常状态,请求可以正常调用依赖服务,同时监控调用的错误率、超时率等指标。打开状态(Open)

h a 6 6 6 c k 为 你解决复杂难题! 1480

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

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

culing2941的博客 1106

SAP SEGW 事物码里的 Association 建模方式

Association 模型用于描述 OData 模型里不同 Entity Type 之间的关联关系。我们来看一个具体的例子:Principal Entity(主体):代表 association 的主导端。Cardinality(基数):指定主体实体类型和依赖实体类型之间的关系。按 F4 或点击从列表中选择。关联的多重性如下:为引用约束()指定以下参数,目的是将主体实体类型的每个键,关联到从属实体类型的一个属性:Referential Constraints 的一个例子如下: 引用约束(Referenti

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 910

Halcon 形态学 开发案例 (开运算opening(先腐蚀再膨胀)、闭运算closing(先膨胀再腐蚀))

算子方法:功能:使用用户自定义的结构元素对区域进行开运算参数: Region(输入参数) :输入区域 StructElement(输入参数) :结构元素(区域) RegionOpening(输出参数) :开运算后的区域功能:使用圆形结构元素对区域进行开运算参数: Region(输入参数) :输入区域 RegionOpening(输出参数) :开运算后的区域 Radius(输入参数) :圆形结构元素的半径功能:使用矩形结构元素对区域进行开运算。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1619

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

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

weixin_30600197的博客 512

Open3D 合并两个点云【2025最新版】

两个点云中的数据连接,博客长期更新,本文最新更新时间为:2025年4月26日。

点云侠的博客 7435

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

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

weixin_34005090的博客 250

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

z4a5b6的博客 178

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

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

weixin_29002595的博客 223

温度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、付费专栏及课程。

余额充值