明显的封装
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的封装。更糟糕的是,它调用了未定义的行为,所以它可能工作,也可能不工作,或者可能崩溃。。。
相关文章:
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将可变参数函数的参数封装在类实例中
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 封装C++模板
- 将 RTOS 队列对象封装在仅具有静态分配的 IQueue 自定义接口中
- 从封装在对象中的函数 C++ 返回时为空的列表
- 当要访问的对象被多次封装时,如何正确使用setter
- 在为嵌套类定义行外友元时,我真的必须打破封装吗?
- 如何在类中封装C/C++套接字发送和接收函数?
- 如何使用吸气剂方法实现C++封装
- 封装 std::map 以允许迭代,但没有直接密钥访问?
- 类C++友元函数无法访问封装的类
- 当从成员类调用封装的std::begin时,程序崩溃
- 从私有成员类中断封装派生的模板类
- C++实用程序,用于将长开关语句转换为封装开关案例阶梯的简洁函数调用
- 如何修复列表视图中的错误?,封装控件时无法选择任何项
- 我们可以使用命名空间实现封装吗?
- 封装 std::vector 以允许迭代,但不允许其他内容
- lambda[=] 上的复制值被另一个封装的 lambda[&] 阻止
- 如何使用提升范围将自定义迭代器封装在函数中