明显的封装

Apparent encapsulation

本文关键字:封装      更新时间:2023-10-16

新命令在堆中分配内存来存储对象。静态分配可能会导致对象被放在堆栈上。但它们都不是记忆的保护区。我可以访问这个,它只是对象的地址,然后使用间接运算符,从而指向对象字段:

string str=string("hello");
void** str_this=(void**)&str;
char* str_data= (char*)*str_this;
str_data[0]='s';
str_data[1]=0;
cout <<str_data; // prints "sello"

那么,这仍然被认为是封装吗?类用户(实例化对象的用户)是否负责避免指向对象的数据?

编程中的封装通常并不意味着"如果你真的尝试了,就不可能解决"。

这通常意味着更接近于"能够明确区分应该暴露与否,以及不会意外暴露或使用物品"。

我认为没有人会把你的代码误认为是按照应该访问字符串的方式访问的。

C++是一种强大的语言。正如一位漫画超级英雄曾经说过的那样,权力越大,责任越大。

一旦将对象指针强制转换为void*,然后将该指针重新转换为另一种类型(在本例中为char*),就进入了未定义行为的领域。如果您尝试使用char*指针,该语言不能保证什么会起作用,什么不会起作用。只有将void*重铸回原始类型(string*)才是合法的。

调用未定义的行为并不是破坏封装的合法方式,因为一旦您越过未定义行为阈值,任何都是可能的(只是不可移植)。

您的代码隐式地依赖于std::string的特定实现。换句话说,您的代码正在破坏std::string的封装。更糟糕的是,它调用了未定义的行为,所以它可能工作,也可能不工作,或者可能崩溃。。。