news 2026/5/22 6:50:17

C++友元函数与友元类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++友元函数与友元类

C++友元函数与友元类

友元机制允许特定的函数或类访问另一个类的私有和保护成员。虽然友元打破了封装性,但在某些场景下可以提供更清晰的接口设计。

友元函数可以访问类的私有成员,常用于运算符重载。

#include
#include

class Vector2D {
double x_, y_;

public:
Vector2D(double x = 0, double y = 0) : x_(x), y_(y) {}

friend Vector2D operator+(const Vector2D& a, const Vector2D& b);
friend Vector2D operator*(const Vector2D& v, double scalar);
friend double dot(const Vector2D& a, const Vector2D& b);
friend std::ostream& operator<<(std::ostream& os, const Vector2D& v);

double magnitude() const {
return std::sqrt(x_ * x_ + y_ * y_);
}
};

Vector2D operator+(const Vector2D& a, const Vector2D& b) {
return Vector2D(a.x_ + b.x_, a.y_ + b.y_);
}

Vector2D operator*(const Vector2D& v, double scalar) {
return Vector2D(v.x_ * scalar, v.y_ * scalar);
}

double dot(const Vector2D& a, const Vector2D& b) {
return a.x_ * b.x_ + a.y_ * b.y_;
}

std::ostream& operator<<(std::ostream& os, const Vector2D& v) {
os << "(" << v.x_ << ", " << v.y_ << ")";
return os;
}

void friend_function_example() {
Vector2D v1(3, 4);
Vector2D v2(1, 2);

Vector2D sum = v1 + v2;
Vector2D scaled = v1 * 2.0;
double product = dot(v1, v2);

std::cout << "v1: " << v1 << "\n";
std::cout << "v2: " << v2 << "\n";
std::cout << "sum: " << sum << "\n";
std::cout << "scaled: " << scaled << "\n";
std::cout << "dot product: " << product << "\n";
}

友元类可以访问另一个类的所有私有成员。

class Engine {
int rpm_;
double temperature_;

friend class Car;

public:
Engine() : rpm_(0), temperature_(20.0) {}

private:
void start() {
rpm_ = 1000;
temperature_ = 90.0;
std::cout << "Engine started\n";
}

void stop() {
rpm_ = 0;
temperature_ = 20.0;
std::cout << "Engine stopped\n";
}
};

class Car {
Engine engine_;
bool running_;

public:
Car() : running_(false) {}

void start() {
if (!running_) {
engine_.start();
running_ = true;
std::cout << "Car started, RPM: " << engine_.rpm_ << "\n";
}
}

void stop() {
if (running_) {
engine_.stop();
running_ = false;
std::cout << "Car stopped\n";
}
}

void display_status() const {
std::cout << "Engine RPM: " << engine_.rpm_
<< ", Temperature: " << engine_.temperature_ << "°C\n";
}
};

void friend_class_example() {
Car car;
car.start();
car.display_status();
car.stop();
}

友元声明可以用于实现特殊的访问控制模式。

class BankAccount {
double balance_;
std::string account_number_;

friend class Bank;
friend class Auditor;

public:
BankAccount(const std::string& number, double initial)
: account_number_(number), balance_(initial) {}

void deposit(double amount) {
if (amount > 0) {
balance_ += amount;
std::cout << "Deposited: " << amount << "\n";
}
}

double get_balance() const {
return balance_;
}
};

class Bank {
public:
void transfer(BankAccount& from, BankAccount& to, double amount) {
if (from.balance_ >= amount) {
from.balance_ -= amount;
to.balance_ += amount;
std::cout << "Transferred " << amount << " from "
<< from.account_number_ << " to " << to.account_number_ << "\n";
} else {
std::cout << "Insufficient funds\n";
}
}
};

class Auditor {
public:
void audit(const BankAccount& account) {
std::cout << "Auditing account " << account.account_number_
<< ", Balance: " << account.balance_ << "\n";
}
};

void access_control_example() {
BankAccount acc1("ACC001", 1000);
BankAccount acc2("ACC002", 500);

Bank bank;
bank.transfer(acc1, acc2, 200);

Auditor auditor;
auditor.audit(acc1);
auditor.audit(acc2);
}

友元函数可以是另一个类的成员函数。

class Display;

class Data {
int value_;

friend void Display::show(const Data& d);

public:
explicit Data(int v) : value_(v) {}
};

class Display {
public:
void show(const Data& d) {
std::cout << "Data value: " << d.value_ << "\n";
}
};

友元关系不是对称的,也不能传递。

class A {
int secret_;

friend class B;

public:
explicit A(int s) : secret_(s) {}
};

class B {
int data_;

public:
explicit B(int d) : data_(d) {}

void access_A(const A& a) {
std::cout << "B accessing A's secret: " << a.secret_ << "\n";
}
};

class C {
public:
void try_access_A(const A& a) {
std::cout << "C cannot access A's secret\n";
}
};

友元机制应该谨慎使用,只在确实需要打破封装时才使用。过度使用友元会降低代码的可维护性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 6:46:28

如何使用代理保护电子邮件营销?如何保护您的收件箱

电子邮件仍然是企业和个人最广泛使用的沟通渠道之一&#xff0c;同时也是网络犯罪分子最常攻击的目标之一。从网络钓鱼和垃圾邮件泛滥到凭证窃取和未经授权的账户访问&#xff0c;电子邮件收件箱时刻面临风险。据行业报告显示&#xff0c;电子邮件仍然是超过 90% 网络攻击的主要…

作者头像 李华
网站建设 2026/5/22 6:41:13

2026年必看:六款热门AI编程工具横评,Trae与Cursor怎么选

2026年必看&#xff1a;六款热门AI编程工具横评&#xff0c;Trae与Cursor怎么选AI编程工具正从辅助插件进化为全流程开发核心&#xff0c;2026年市场进入智能体协作新阶段。本文精选6款主流AI编程工具&#xff0c;从核心功能、协作模式、适配场景等维度深度解析&#xff0c;帮开…

作者头像 李华
网站建设 2026/5/22 6:39:26

Token聚合平台 vs 传统云 vs AI原生云,AI推理应用怎么选?

在大模型能力深度融入生产环境的当下&#xff0c;后端 AI 架构的选择往往决定了应用的生死。从早期的“调用一个接口”到如今复杂的智能体&#xff08;Agent&#xff09;工作流&#xff0c;开发团队在底座选型上面临着两条截然不同的演进路径&#xff1a;一条是追求便利与极致轻…

作者头像 李华
网站建设 2026/5/22 6:27:25

开源软件的开发与贡献:如何参与开源项目

一、开源项目&#xff1a;软件测试从业者的新赛道在软件行业快速迭代的今天&#xff0c;开源项目早已不再是开发者的专属领地。对于软件测试从业者而言&#xff0c;参与开源项目不仅是提升专业能力的绝佳途径&#xff0c;更是拓展职业边界、积累行业资源的重要方式。开源项目的…

作者头像 李华
网站建设 2026/5/22 6:25:07

(二) 1. Q-learning的遗憾界分析-高效的Q-learning算法

高效的Q-learning算法 1.1. 无模型算法 1.2. UCB算法 1.3. 文献回顾 无模型(Model-free)强化学习算法(如 Q-learning)无需显式地对环境进行建模,而是直接对价值函数或策略进行参数化和更新。与基于模型(Model-based)的方法相比,这类算法通常更简单、更灵活,因此在现代…

作者头像 李华