1. 基本概念对比
js
// JavaScript中的对象传递(始终是引用)
const obj = { x: 10 };
function modifyObject(object) {
object.x = 20; // 直接修改原对象
}
modifyObject(obj);
console.log(obj.x); // 输出: 20
cpp
// C++中需要显式指定是否传递引用
struct Point { int x; };
// 方式1: 值传递(拷贝)- 类似JavaScript的基本类型
void modifyByValue(Point p) {
p.x = 20; // 只修改副本,原对象不变
}
// 方式2: 引用传递(类似JavaScript的默认行为)
void modifyByReference(Point& p) {
p.x = 20; // 直接修改原对象
}
Point point{10};
modifyByValue(point); // point.x 仍然是 10
modifyByReference(point); // point.x 变成 20
js中有基本类型(值类型 )和对象类型(引用类型)
值类型 :字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
引用类型 :对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)
在js中不需要考虑是值传递还是引用传递,由js引擎在执行时动态判断是哪种方式,对我们开发者来说代码简单,但是对电脑来说执行耗时
2. 引用声明(&)
cpp
int value = 42;
int& ref = value; // ref 是 value 的引用(别名),这是引用传递
// 这里是浅拷贝
int value = 42;
int ref = value; // 这是值传递
// 这里是深拷贝
// 相当于JavaScript中的:
// let value = 42;
// let ref = value; // 在JavaScript中,基础类型是值传递的
// 这里是深拷贝
在js中number等基本类型都是值传递,我们无法控制number使用引用传递。同理object等引用类型都是引用传递,我们无法控制他使用值传递。
在c++我们可以任意控制是使用值传递还是引用传递。
cpp
int& ref = value;
int &ref = value;
// 在语法和功能上完全等价,没有任何区别
// 风格差异(非技术性):
// `int& ref`:强调"引用类型",认为`int&`是一个整体类型
// `int &ref`:强调"ref是一个引用变量",认为`&`是变量修饰符
语法形式 | 说明 | 示例 |
---|---|---|
类型& 变量名 = 初始值 | 声明引用 | int& r = x; |
函数(类型& 参数名) | 引用参数 | void f(int& x) |
类型& 函数名() | 返回引用 | int& getRef() |
const 类型& 变量名 | 常量引用 | const int& cr = x; |
3. 两种设计哲学对比
3.1 JavaScript: "简单易用优先"
js
// JavaScript - 一切都很"自动"
function processData(data) {
data.x = 100; // 自动引用传递
let copy = {...data}; // 需要拷贝时显式声明
return data; // 自动内存管理
}
3.2 C++: "性能控制优先"
cpp
// C++ - 明确控制每一个细节
void processData(Data& data) { // 显式声明:我要引用传递
data.x = 100; // 修改原对象
}
void processData(Data data) { // 显式声明:我要值传递(拷贝)
data.x = 100; // 只修改副本
}
void processData(const Data& data) { // 显式声明:只读引用
// data.x = 100; // 编译错误!不能修改
}
c++中为什么要显式的控制,和js一样设计成隐式控制,不是会更好的理解和阅读吗
js是解释型语言,可以在执行时动态处理一些数据,虽然语法上简单了,但把一些流程操作在js引擎里默默地处理了(在计算机中,所有语言的底层原理,执行流程都是一样的),但是这也增加了代码运行时间
c++是编译型语言,这种显式控制的语法,可以在编译时明确告诉编译器如何处理,给了编译时的优化空间
鄙人愚见
在计算机中,所有语言的底层原理,执行流程都是一样的,就是上层语法,架构设计不一样。这种上层的差异性是语言在不同的应用场景下的产物。没有一种语言可以完美的应对所有场景,这也是有这么多五花八门的语言的原因。