C++面向对象(十三):友元、内部类、局部类
友元
- 友元包括友元函数和友元类
- 如果将函数A(非成员函数)声明为类C的友元函数,那么函数A就能直接访问类C对象的所有成员
- 如果将类A声明为类C的友元类,那么类A的所有成员函数都能直接访问类C对象的所有成员
- 友元破坏了面向对象的封装性,但在某些频繁访问成员变量的地方可以提高性能
友元函数:
#include <iostream>
using namespace std;
class Point {
// 声明友元函数(返回值、参数、函数名),只要放在类里面就行
friend Point add (Point, Point);
int m_x;
int m_y;
public:
int getX () { return m_x; };
int getY () { return m_y; };
Point(int x, int y) :m_x(x), m_y(y) {}
void display () {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};
Point add (Point p1, Point p2) {
// 每调用一次都有4次栈空间的开辟和回收
//return Point (p1.getX () + p2.getX (), p1.getY () + p2.getY ());
// 直接访问私有成员
return Point (p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
int main () {
Point p1 (6, 6);
Point p2 (6, 6);
Point p3 = add (p1, p2);
p3.display ();
getchar ();
return 0;
}
友元类:
#include <iostream>
using namespace std;
class Point {
// 友元类
friend class Math;
int m_x;
int m_y;
public:
int getX () { return m_x; };
int getY () { return m_y; };
Point(int x, int y) :m_x(x), m_y(y) {}
void display () {
cout << "(" << m_x << ", " << m_y << ")" << endl;
}
};
class Math {
public:
Point add (Point p1, Point p2) {
// 直接访问
return Point (p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
};
int main () {
Point p1 (6, 6);
Point p2 (6, 6);
Point p3 = Math().add(p1, p2);
p3.display ();
getchar ();
return 0;
}
内部类(嵌套类)
如果将类A定义在类C的内部,那么类A就是一个内部类(嵌套类)
内部类的特点:
- 支持public、protected、private权限
- 成员函数可以直接访问其外部类对象的所有成员(反过来则不行)
- 成员函数可以直接不带类名、对象名访问其外部类的static成员
- 不会影响外部类的内存布局
- 可以在外部类内部声明,在外部类外面进行定义
#include <iostream>
using namespace std;
class Person {
int m_age;
static int m_height;
static void run();
public:
//private:
//protected:
// 内部类能控制类的访问范围
// 不影响外部类的内存布局,只是访问权限改变了
class Car {
int m_price;
void run () {
Person person;
// 可以直接访问外部类的所有成员
person.m_age = 6;
// 可以直接访问静态成员
m_height = 66;
run();
}
};
};
int main() {
// 实例化一个car对象
Person::Car car;
getchar();
return 0;
}
可以声明与实现分离:
// 里面声明外面实现
class Point {
class Math {
void test();
};
};
void Point::Math::test() {}
// 里面声明外面实现
class Point {
class Math;
};
class Point::Math {
void test() {}
};
// 里面声明外面实现
class Point {
class Math;
};
class Point::Math {
void test();
};
void Point::Math::test() {}
局部类
在一个函数内部定义的类,称为局部类
局部类的特点:
- 作用域仅限于所在的函数内部
- 其所有的成员必须定义在类内部,不允许定义static成员变量
- 成员函数不能直接访问函数的局部变量(static变量除外)
void test() {
static int age = 6;
// 局部类
class Car {
// 需要在外面初始化,这样矛盾了
// static int m_price;
void run() { age = 666; }
};
}