函数指针小知识以及类内成员函数为何能访问同类私有成员

1. 函数指针只能指向 无捕获的Lambda

Lambda 表达式如果 没有捕获外部变量,它就可以隐式转换为普通函数指针。

✅ 示例:
void callFunc(int (*func)(int)) {
    std::cout << func(10) << std::endl;
}

int main() {
    auto lambda = [](int x) { return x * 2; }; // 无捕获
    callFunc(lambda); // OK!
    return 0;
}

✅ 等价于:

int (*funcPtr)(int) = [](int x) { return x * 2; };
funcPtr(5); // 返回 10

原因: 无捕获 Lambda 会被编译器转换成一个普通函数,和函数指针兼容。


❌ 捕获变量的 Lambda 不行!

int base = 100;
auto lambda = [base](int x) { return base + x; }; // 捕获了 base

// callFunc(lambda); // ❌ 错误:不能将带捕获的 lambda 转换为函数指针

❌ 带捕获的 Lambda 是一个有状态的匿名类对象,不能隐式转换成函数指针。


💡 想传递捕获 Lambda?用 std::function

#include <functional>

void callFunc(std::function<int(int)> func) {
    std::cout << func(10) << std::endl;
}

int main() {
    int base = 100;
    auto lambda = [base](int x) { return base + x; }; // 有捕获
    callFunc(lambda); // OK!
}

🧠 总结:

Lambda 类型可转换为函数指针原因
无捕获 [ ]✅ 可以编译器生成的是静态函数
有捕获 [=], [&]❌ 不可以生成的是闭包对象

2. 类内成员函数为何能访问同类私有成员

#include <thread>
#include <iostream>

class A {
public:
    A(int i) : _i{i} {}
    A(const A & other)	//error const 不能被移动
    {
        _i = other._i;
        _t = std::move(other._t);
    }
    int GetIndex() const { return _i; }
private:
    std::thread _t;
    int _i;
};

int main(int argc, char **argv)
{
   
    A a(1);
    std::cout << "member _i is " << a.GetIndex() << std::endl;

    return 0;
}

_t_i 都是私有成员(private),为什么在 A(const A& other) 中可以访问 other._iother._t

答案其实是这样的:


在类的成员函数内部访问同类对象的私有成员是合法的

这是 C++ 的一个语言特性。

在类的成员函数中(包括构造函数、析构函数、成员方法等),你可以访问

  • 当前对象的私有/保护成员(这是显然的);
  • 其他同类对象(即同类型实例)的私有/保护成员。

💡 举个例子说明:

class Example {
private:
    int _x;
public:
    Example(int x) : _x{x} {}
    void CopyFrom(const Example& other) {
        _x = other._x; // ✅ 合法,虽然 _x 是私有的
    }
};

这里 other._x 是私有成员,但 CopyFrom()Example 的成员函数,所以它可以访问 任意 Example 对象的私有成员


🤔 为什么 C++ 要这么设计?

因为:

  • 成员函数被认为是“代表整个类的行为”;
  • 所以,它可以操作同类的其他实例的内部状态;
  • 这为实现拷贝构造、比较、赋值运算符重载等提供了必要能力。

🧠 类比一下

你可以把这个设计类比成“成员函数 = 内部朋友”,它有资格互相访问类内的隐私。所以并不是“在类外访问”,而是“在类内部函数中访问别的对象的私有成员”。


✅ 所以这行代码是没问题的:

_i = other._i; // 合法,_i 是私有成员,但我们在类的成员函数中访问

但你之前提到的 _t = std::move(other._t) 出问题不是因为访问权限,而是因为 otherconst,不能对 const 对象的成员调用 std::move()(移动会修改对象状态)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值