C++语言深入理解类的封装与数据隐藏

简介: 深入理解类的封装与数据隐藏

封装不单纯只是提供一个封皮,封装的是数据抽象出的属性与行为,封装提供了访问控制,可以实现数据隐藏与访问接口,封装提供了作用域与命名空间的界定。封装让数据的颗粒度变得更大,有利于程序的积木式搭建。当然,封装也是继承与多态的基石。

class ClassName // member encapsulation, data hiding through access level
// a base address, name expanding, namespace, scope
{ // {}形成封装,有数据隐藏,有接口
private: // private与{}一起形成数据隐藏,{}外面的部分(包括其子类)无法访问{}内的pvivate部分
// (可以被内部的部分访问)
// but not private for friends of functions or classes
// Declarations of private
// members appear here.
protected: // 本类、子类成员函数、友元可以访问,此外,外部不能被访问
public: // public部分形成封装的接口,与外界交互
// Declarations of public
// members appear here.
// static members // 由类名即可以访问,类名相当于命名空间或标识符扩展(name expanding)
// virtual functions // 被继承重载时可扩展
// abstract class(virtual and "=0" notation) forms interface
// friend ostream &operator << (ostream &, const className &);
}; // 尽量暴露方法,不要暴露数据
// static data member must be defined outside the class declaration
// Separating a class into specification and implementation files
// 在外定义成员需使用作用域限定操作符(scope resolution operator)::限定成员名称
// ReturnType ClassName :: functionName ( ParameterList ){} // member name extending
示意图:

一个简单实例:

class Rectangle
{
private:
double width;
double length;
static int counting;
public:
void setWidth(double);
void setLength(double);
double getWidth() const;
double getLength() const;
double getArea() const;
friend ostream &operator << (ostream &, const Rectangle &);
};
int Rectangle::counting = 0;
不同继承方式形成的访问权限:

实例:

include

class A{
private:
int x;
protected:
int y;
public:
int z;
A(int a,int b,int c){
x=a;
y=b;
z=c;
}
};
class B:private A{
private:
int p;
public:

//代码效果参考:http://www.zidongmutanji.com/bxxx/486446.html
B(int a,int b,int c,int d):A(a,b,c){p=d;}
int sum(){
return y+z;
}
};
main()
{
A a(1,2,3);
printf("%d\n",a.z); // 3
B b(1,2,3,4);
printf("%d\n",b.sum());// 5
//printf("%d\n",b.z);
getchar();
}
类封装形成的数据隐藏可以保证数据的安全性、完整性。在保证接口的稳定性后, 当外部只访问接口时,接口实现的改变以及private部分的变更,都无须变更已使用该类接口的代码。

相关文章
|
2天前
|
设计模式 安全 编译器
【C++11】特殊类设计
【C++11】特殊类设计
22 10
|
7天前
|
C++
C++友元函数和友元类的使用
C++中的友元(friend)是一种机制,允许类或函数访问其他类的私有成员,以实现数据共享或特殊功能。友元分为两类:类友元和函数友元。类友元允许一个类访问另一个类的私有数据,而函数友元是非成员函数,可以直接访问类的私有成员。虽然提供了便利,但友元破坏了封装性,应谨慎使用。
39 9
|
2天前
|
C++ 容器
【C++】map和set封装
【C++】map和set封装
9 2
|
2天前
|
存储 编译器 C语言
【C++基础 】类和对象(上)
【C++基础 】类和对象(上)
|
10天前
|
编译器 C++
【C++】string类的使用④(字符串操作String operations )
这篇博客探讨了C++ STL中`std::string`的几个关键操作,如`c_str()`和`data()`,它们分别返回指向字符串的const char*指针,前者保证以&#39;\0&#39;结尾,后者不保证。`get_allocator()`返回内存分配器,通常不直接使用。`copy()`函数用于将字符串部分复制到字符数组,不添加&#39;\0&#39;。`find()`和`rfind()`用于向前和向后搜索子串或字符。`npos`是string类中的一个常量,表示找不到匹配项时的返回值。博客通过实例展示了这些函数的用法。
|
2天前
|
存储 C++ 容器
【C++】开散列实现unordered_map与unordered_set的封装
【C++】开散列实现unordered_map与unordered_set的封装
9 0
|
4天前
|
安全 算法 编译器
C++一分钟之-内存模型与数据竞争
【7月更文挑战第10天】了解C++11内存模型对多线程编程至关重要。它定义了线程间同步规则,包括顺序一致性、原子操作和内存屏障。数据竞争可能导致不确定行为,如脏读和丢失更新。可通过互斥量、原子操作和无锁编程避免竞争。示例展示了`std::mutex`和`std::atomic`的使用。掌握内存模型规则,有效防止数据竞争,确保多线程安全和性能。
11 0
|
10天前
|
C++
【C++】string类的使用④(常量成员Member constants)
C++ `std::string` 的 `find_first_of`, `find_last_of`, `find_first_not_of`, `find_last_not_of` 函数分别用于从不同方向查找目标字符或子串。它们都返回匹配位置,未找到则返回 `npos`。`substr` 用于提取子字符串,`compare` 则提供更灵活的字符串比较。`npos` 是一个表示最大值的常量,用于标记未找到匹配的情况。示例代码展示了这些函数的实际应用,如替换元音、分割路径、查找非字母字符等。
|
10天前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
10天前
|
C++
C++】string类的使用③(修改器Modifiers)
这篇博客探讨了C++ STL中`string`类的修改器和非成员函数重载。文章介绍了`operator+=`用于在字符串末尾追加内容,并展示了不同重载形式。`append`函数提供了更多追加选项,包括子串、字符数组、单个字符等。`push_back`和`pop_back`分别用于在末尾添加和移除一个字符。`assign`用于替换字符串内容,而`insert`允许在任意位置插入字符串或字符。最后,`erase`函数用于删除字符串中的部分内容。每个函数都配以代码示例和说明。