C++ API:修改内部对象
C++ API: Modifing internal objects
我有两个相关的问题。 目前,我正在设计/编写一个C++ API,其中我需要能够修改由另一个对象持有的对象。
它与此示例相当:
class Bar
{
public:
Bar(int x) : num(x){}
void setNum(int x)
{
num = x;
}
int getNum()
{
return num;
}
private:
int num;
};
class Foo
{
public:
Foo() = default;
void setBar(std::unique_ptr<Bar> newBar)
{
bar = std::move(newBar);
}
Bar* getBar()
{
return bar.get();
}
private:
std::unique_ptr<Bar> bar;
};
然而,类Foo
拥有Bar
的所有权,Bar
必须能够被修改。 在这里,Foo
是用户将与之交互的主要类。 虽然Bar
可以更多地被视为一种数据类型,但它会改变Foo
的输出。
返回原始指针以Bar
的解决方案是首选选项吗? 我有一种感觉,这阻止了封装,这对于 API 设计来说是不行的。 我在谷歌上搜索的努力还没有给我一个具体的答案。 但我可能只是用错误的搜索词看。
这个问题的第二部分是,如果Bar
存储在Foo
的容器中,此示例将如何变化。 我会返回指向整个容器的指针,容器的迭代器吗?
如果您担心getBar
破坏封装,那么您还应该void setBar(std::unique_ptr<Bar> newBar)
视为这样的破坏。
因为允许从外部设置bar
确实使得关于bar
的知识可能没有专属于Foo
,而传递给Foo
Bar
的知识可能仍然有可能修改bar
,因此Foo
不能对Bar
的状态做任何假设,因为它可以随时更改。
另一方面,如果您只想对Bar
槽Foo
进行读取访问,那么const Bar* getBar()
或const Bar& getBar()
不会破坏封装,因为getBar
不允许更改Bar
。
返回原始指针到 Bar 的解决方案是首选选项吗?
这是一个解决方案,不一定是一个坏解决方案。在对象始终存在的情况下,返回引用会更可取(在这种情况下不是,因为Foo
的默认构造函数不会创建Bar
(。
一些程序员更喜欢对裸指针使用包装器(例如observer_ptr
,这已被提议用于标准(,以将其与旨在迭代数组的指针或拥有裸指针(应避免使用后者(区分开来。
我有一种感觉,这阻止了封装
你的整个前提是打破封装,因为你想"修改内部对象"。如果要避免封装中断,则可能需要进一步更改设计,以便无需修改内部对象(外部(。
不破坏封装的解决方案是提供一个特定的接口来Foo
进行修改,例如:
void Foo::transmogrify_bar(int gadgets) {
bar->transmofgrify(gadgets);
}
此封装是否对您的 API 有用是另一回事。在某些情况下,这是必不可少的,而在其他情况下,这并不重要。
如果 Bar 将存储在 Foo 的容器中。我会返回指向整个容器的指针,容器的迭代器吗?
是否希望客户端能够修改容器(添加、删除元素(?
这进一步打破了封装。相反,您可以begin
和end
不允许修改容器本身的迭代器,这会在单个对象的情况下对指针返回进行等效封装。
您可以仅提供 const 迭代器,并将迭代器作为参数添加到transmogrify
以保持修改Bar
的封装。
最后,对于完全封装,您需要使用 PIMPL 模式来完全隐藏Bar
。
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 对象内部对象的重载功能
- std::使用内部对象移动 - 与调用不匹配
- C++ API:修改内部对象
- QML:如何将动态创建的组件与自定义的内部对象一起使用
- 使用基对象修改/访问派生类的信息的有问题的设计
- 如何修改/更新通过 const 引用传递的对象的内部状态
- 如果一个类是基于指针的,那么内部对象必须是基于指针还是不基于指针
- 从函数中抛出内部对象异常合法吗
- 对象修改通知
- BinaryFormatter在转换Int32和Double等内部对象时出现问题
- 从c++中GUI中创建的对象修改GUI
- 将lambda传递给对象并在lambda内部修改该对象
- 从复制构造函数外部修改对象成员时导致向量内存损坏,但从复制构造函数内部修改时不会
- 从lambda的内部框架修改via闭包中的变量安全吗?lambda是从一个不再存在的函数创建的
- Pimpl习语和内部对象协作,无需友元声明
- 返回对内部对象的引用时的常量
- 将等待多个对象修改*多个*对象的状态
- 指向对象方法内部对象的null指针