ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 一.友元 1. **功能** 让其他类和函数访问类的非公有成员。 2. **友元的声明** 将函数或类或类的成员函数声明放入类,并在声明左边加上 `friend` >[warning] 以下例子可在 除VC++6.0 外的编译器下运行 ```c++ #include <iostream> using namespace std; class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) { } Complex(double real) : real_(real), imaginary_(0) { } Complex(double real, double imaginary) : real_(real), imaginary_(imaginary) { } Complex(const Complex &old) { this->real_ = old.real_; this->imaginary_ = old.imaginary_; } Complex &operator=(const Complex &old) { this->real_ = old.real_; this->imaginary_ = old.imaginary_; return *this; } Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } friend ostream &operator<<(ostream &os, Complex c);//友元函数的声明 }; ostream &operator<<(ostream &os, Complex c) { return os << '(' << c.real_ << ',' << c.imaginary_ << ')'; } int main() { Complex c(2, 3); cout << c; return 0; } ``` >[test] >(2,3) 3. **VC++6.0友元函数BUG** + 当引入不带 `.h` 的头文件 且 使用了命名空间 std 时,将运算符重载函数作为友元函数将无法访问类的私有成员。 + 解决方案 1. 使用带 `.h` 的头文件,此时不需要使用命名空间 `std` 2. 不要 `using namespace std` ,需要什么标识符就使用什么标识符 > 以下示例可在任意标准的C++中运行 ```c++ #include <iostream> //需要什么标识符就使用什么标识符 using std::ostream; using std::cout; class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) { } Complex(double real) : real_(real), imaginary_(0) { } Complex(double real, double imaginary) : real_(real), imaginary_(imaginary) { } Complex(const Complex &old) { this->real_ = old.real_; this->imaginary_ = old.imaginary_; } Complex &operator=(const Complex &old) { this->real_ = old.real_; this->imaginary_ = old.imaginary_; return *this; } Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } friend ostream &operator<<(ostream &os, Complex c); }; ostream &operator<<(ostream &os, Complex c) { return os << '(' << c.real_ << ',' << c.imaginary_ << ')'; } int main() { Complex c(2, 3); cout << c; return 0; } ``` >[test] >(2,3) 4. **好处** 灵活 5. **弊端** 破坏的类的封装性