1. 封装
在C++中,封装是一种将数据和操作数据的函数封装在一起的机制。它可以将数据隐藏起来,只提供公共接口给外部使用,从而保证数据的安全性和一致性。
封装的目的是将数据和相关操作封装在一起形成一个类,对外部使用者隐藏内部的实现细节。这样做的好处是可以隐藏数据的具体实现,提高代码的安全性和可维护性。
在C++中,封装主要通过类和访问控制来实现。类将数据成员和成员函数封装在一起,通过访问控制符(public、private、protected)来控制成员的访问权限。数据成员通常被声明为私有(private),只能通过公有(public)的成员函数来访问、修改数据。
| 权限 | 类内 | 类外 | 派生类 |
| public | 可以访问 | 可以访问 | 可以访问 |
| protected | 可以访问 | 不可访问 |
可以访问父类的 |
| private | 可以访问 | 不可访问 |
不可访问 |
封装的优点包括:
-
隐藏实现细节:封装使得实现细节对外部使用者不可见,只提供了一个抽象的接口。这样可以避免外部使用者了解或依赖于具体的实现细节,提高代码的安全性和可维护性。
-
简化接口:通过封装,可以将一组相关的数据和操作组织在一起,形成一个类。外部使用者只需要使用类提供的公共接口,而不需要了解内部的实现细节,从而简化了接口的使用。
-
提高代码复用性:类可以被多次实例化,每个实例都具有相同的数据结构和操作方法。这样可以提高代码的复用性,避免了重复编写相同功能的代码。
-
隔离变化:封装可以将类的实现细节与外部使用者分离开来,使得变化的影响范围最小。当类的实现发生变化时,只需要修改类的内部,而不需要修改外部使用者的代码。
总之,封装是C++中一种重要的特性,可以提高代码的安全性、可维护性和复用性。通过合理的封装,可以隐藏实现细节,简化接口,并隔离变化,使得代码更加健壮和可扩展。
1> 访问控制符,封装中的护城河
C++访问控制符用于控制类的成员(包括变量和函数)的访问权限,包括三种控制符:
-
public: 公有控制符,表示成员可以在类的内部和外部进行访问。任何地方都可以访问公有成员。
-
private: 私有控制符,表示成员只能在类的内部进行访问,外部无法直接访问私有成员。可以通过类的公有成员函数来间接访问私有成员。
-
protected: 保护控制符,类似于私有控制符,表示成员只能在类的内部进行访问,外部无法直接访问保护成员。不同的是,派生类可以直接访问基类的保护成员。
通过访问控制符,可以实现类的封装性和数据隐藏。公有成员提供给外部访问,私有成员只能在类内部使用,保护成员提供给派生类使用。这样可以防止外部直接修改类的私有成员,从而提高类的安全性和数据的完整性。
C++类中的默认控制符是private,与之区分的是C中的struct,它的默认控制符是public。
2> friend 封装中的双刃剑
在C++中,友元(friend)是一种特殊的函数或类,它可以访问另一个类中的私有成员。友元函数或类可以在被访问的类中声明为友元,从而被授权访问私有成员。
友元函数在类声明中使用关键字"friend"声明,如下所示:
class MyClass {
public:
MyClass(int num) : number(num) {}
friend void friendFunction(MyClass& obj);
private:
int number;
};
void friendFunction(MyClass& obj) {
// 可以访问MyClass中的私有成员
std::cout << "Private member of MyClass accessed: " << obj.number << std::endl;
}
在这个例子中,friendFunction函数被声明为MyClass的友元函数,因此它可以直接访问MyClass中的私有成员number。
友元类的声明方式类似于友元函数,只是将类名作为关键字"friend"后的参数,如下所示:
class MyClass {
public:
MyClass(int num) : number(num) {}
friend class FriendClass;
private:
int number;
};
class FriendClass {
public:
void accessPrivateMember(MyClass& obj) {
// 可以访问MyClass中的私有成员
std::cout << "Private member of MyClass accessed: " << obj.number << std::endl;
}
};
在这个例子中,FriendClass被声明为MyClass的友元类,因此它可以直接访问MyClass中的私有成员number。
需要注意的是,友元函数或类的声明并不属于类的成员函数或成员类。因此,在使用友元函数或类时,应在类的声明中将其声明为友元,而在类的实现中定义和实现它们。
3> 重载 封装中的套路
C++中的重载(Overload)是指在同一个作用域内,可以定义多个同名函数,但其参数列表必须不同。重载的函数可以根据不同的参数类型和个数进行调用,使得程序具有更灵活的使用性。
C++中函数的重载可以通过以下几种方式实现:
1. 参数个数不同:函数名相同,但参数个数不同,可以实现重载。例如:
void foo(int x);
void foo(int x, int y);
2. 参数类型不同:函数名相同,但参数类型不同,可以实现重载。例如:
void foo(int x);
void foo(double x);
3. 参数顺序不同:函数名相同,但参数类型相同,但参数顺序不同,可以实现重载。例如:
void foo(int x, double y);
void foo(double y, int x);
4. 常量性不同:函数名相同,但参数类型相同,但其中一个函数是const成员函数,可以实现重载。例如:
class MyClass {
public:
void print() const;
void print();
};
需要注意的是,重载函数的返回类型并不参与函数重载的判断。
当调用一个重载函数时,编译器会根据函数调用时的实参类型和个数,选择最合适的重载函数进行调用。如果存在多个重载函数都能匹配调用参数,编译器会进行一系列的匹配规则判断,选择最佳匹配的重载函数。
重载函数的命名应该尽量清晰和准确,以避免产生歧义和误导。同时,在使用重载时,需要注意函数调用的实参类型和个数,确保调用的重载函数是符合预期的。
4> 静态成员
C++中的静态成员是类的成员,与类的实例对象无关,它被所有的类实例共享。而非静态成员是每个类实例独有的。
静态成员可以是静态变量或静态函数。
静态变量: 静态成员变量在类声明中以static关键字定义

本文围绕C++展开,详细介绍了封装机制,包括访问控制符、友元、重载、静态成员、构造与析构函数等;阐述了虚函数的使用,如虚函数列表、重写、多态、纯虚函数和抽象类;还讲解了继承概念,包含继承的访问控制、单继承、多继承和虚继承等内容,有助于提升代码安全性和可维护性。
最低0.47元/天 解锁文章
1894

被折叠的 条评论
为什么被折叠?



