Go/C++ 指针比较

本文比较了 Go 和 C/C++ 对指针的使用,理解 Go 指针的设计如何在保留 C/C++ 指针优点的基础上解决其带来的安全问题。原文:Pointers Made Painless: How Go Solves C/C++'s Biggest Headache

世界上很少有事物能在同一特性上同时兼具强大与脆弱的特质。在编程领域,如果要我举例的话,那就是 C/C++ 语言中的指针。

在系统编程领域,指针带来的好处毋庸置疑 ------ 能够实现极高的运行速度和底层控制能力。

世界各地的开发者们已经用了 30-40 年的指针,所有事物都会不断变化发展,指针是否也应该随之发展呢?

倘若保留指针的功能,同时又能让其使用起来更加简便、减少出错的可能性,会怎样呢?这就有了 Go 语言,它旨在简化现代编程。

例 1:自动内存管理

Go:无内存泄漏

在 Go 中,内存管理由垃圾收集器处理,不需要手动分配或释放内存,从而防止内存泄漏。

golang 复制代码
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func createPerson() *Person {
    return &Person{Name: "Alice", Age: 30} // 自动管理内存
}

func main() {
    p := createPerson()
    fmt.Println(p.Name) // 不需要释放内存  
}
C/C++

在 C/C++ 中,必须手动管理内存,忘记释放内存会导致内存泄漏。

c 复制代码
#include <iostream>
#include <string>

struct Person {
    std::string Name;
    int Age;
};

Person* createPerson() {
    return new Person{"Alice", 30}; // 手动分配内存
}

int main() {
    Person* p = createPerson();
    std::cout << p->Name << std::endl;
    // 忘记删除 p? 内存泄露!
    // delete p; 
}

例 2:Nil指针安全

Go:Nil指针安全

在 Go 中,访问 nil 指针不会导致程序崩溃。相反,只会返回零值或 panic(如果试图解引用的话)。

golang 复制代码
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    var p *Person // p 是 nil
    if p != nil {
        fmt.Println(p.Name) // 检查 nil 是安全的
    } else {
        fmt.Println("p is nil") // 优雅地处理 nil 指针
    }
}
C/C++

在 C/C++ 中,解引用空指针会导致未定义行为,通常会导致崩溃(segmentation fault)。

c 复制代码
#include <iostream>
#include <string>

struct Person {
    std::string Name;
    int Age;
};

int main() {
    Person* p = nullptr; // p is null
    std::cout << p->Name << std::endl; // 崩溃: null 指针解引用
}

例 3:更好的解引用方法

Golang
golang 复制代码
// Go: 用指针访问结构体字段
type Person struct {
    Name string
    Age  int
}

func main() {
    p := &Person{Name: "Alice", Age: 30}
    fmt.Println(p.Name) // 即使 'p' 是指针,也不需要 '->',只需要用 '.'
}
C/C++
c 复制代码
// C++: 用指针访问结构体字段
struct Person {
    std::string Name;
    int Age;
};

int main() {
    Person* p = new Person{"Alice", 30};
    std::cout << p->Name; // 'p' 是指针,需要通过 '->' 访问
    delete p; // 别忘了释放内存!
}

你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。为了方便大家以后能第一时间看到文章,请朋友们关注公众号"DeepNoMind",并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的支持和动力,激励我持续写下去,和大家共同成长进步!

相关推荐
EmbedLinX7 小时前
嵌入式之协议解析
linux·网络·c++·笔记·学习
wangjialelele7 小时前
Linux中的进程管理
java·linux·服务器·c语言·c++·个人开发
历程里程碑7 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
李日灐7 小时前
C++进阶必备:红黑树从 0 到 1: 手撕底层,带你搞懂平衡二叉树的平衡逻辑与黑高检验
开发语言·数据结构·c++·后端·面试·红黑树·自平衡二叉搜索树
汉克老师7 小时前
GESP2025年6月认证C++二级( 第一部分选择题(1-8))
c++·循环结构·表达式·分支结构·gesp二级·gesp2级
rainbow68897 小时前
C++高性能框架Drogon:后端开发新标杆
c++
Q741_1477 小时前
C++ 优先级队列 大小堆 模拟 力扣 703. 数据流中的第 K 大元素 每日一题
c++·算法·leetcode·优先级队列·
Yu_Lijing8 小时前
网络复习篇——网络基础(一)
网络·c++·笔记
Bella的成长园地8 小时前
为什么c++中的条件变量的 wait() 函数需要配合while 循环或谓词?
c++·面试
charlee448 小时前
为什么现代 C++ 库都用 PIMPL?一场关于封装、依赖与安全的演进
c++·智能指针·raii·pimpl·编译防火墙·封装设计