C++ 嵌套c+中的封装困难+;班级
我们都熟悉封装和抽象的概念,但有时这可能会导致一个障碍。我很好奇解决问题的技巧或方法,或者你所说的任何东西C++ 嵌套c+中的封装困难+;班级,c++,encapsulation,abstraction,C++,Encapsulation,Abstraction,我们都熟悉封装和抽象的概念,但有时这可能会导致一个障碍。我很好奇解决问题的技巧或方法,或者你所说的任何东西 这里有嵌套C++类: #include <iostream> using namespace std; class Foo { public: int get_foo_var() { return foo_var; } void set_foo_var(int a) { foo_var = a; }
这里有嵌套C++类:
#include <iostream>
using namespace std;
class Foo {
public:
int get_foo_var()
{
return foo_var;
}
void set_foo_var(int a)
{
foo_var = a;
}
private:
int foo_var;
};
class Bar {
public:
Foo get_foo()
{
return foo;
}
private:
Foo foo;
};
int main()
{
Bar bar;
bar.get_foo().set_foo_var(2);
cout << bar.get_foo().get_foo_var() << endl;
}
但我认为这违反了封装和抽象!抽象的整个概念是,如果“foo”与“foo”相关,“bar”与“bar”相关,那么大多数foo操作都应该在foo类中完成,一些操作可以应用于其他类。第一种情况如何?(在这种情况下,foo操作与Bar无关,因此在Bar中操作foo是愚蠢的!)是否要返回某个对象的副本或引用是高级设计决策。这两种方法都是必需的,具体取决于上下文 在此特定示例中,您可以在
Bar
中添加相应的方法来修改其后面的Foo
:
class Bar {
public:
void set_foo_var(int a) {
foo.set_foo_var(a);
}
private:
Foo foo;
};
这是好还是坏?答案是:我们不能告诉你。通常,很难用“Foo”和“Bar”这样的名字来认真地谈论好的类设计。什么是好的和坏的取决于实际的、真实的使用场景!:) 让我们从一个纯粹的概念层面来看一分钟。这就是您的设计所说的:
class Bar {
public:
Foo get_foo()
{
return foo;
}
set_foo(Foo new_foo)
{
// Update foo with new_foo's values
foo = new_foo;
}
private:
Foo foo;
};
在本例中,Foo反映了请求时Bar内部状态的某些部分,但与它来自的Bar无关。您必须显式调用
set\u foo()
来更新工具栏。如果没有这一要求,Foo实际上在概念上就是一个成员变量,不管您如何实现它。为什么您认为返回引用违反了封装?@Brian:这种担心并非毫无根据。事实上,将非常量引用返回到私有成员通常会破坏封装(那么您也可以将该成员设置为非私有)。但这要看情况而定。@BrianBi这有点像公私观念。通过将某些内容设置为“私有”,可以限制对原始数据的直接访问。获取引用正是提供原始数据。不是吗?@ChristianHackl但在这种情况下,他希望客户端能够修改内部Foo
。无论如何,我认为你的答案是好的,但我仍然不太理解这里的设计理念。请拿出现实生活中的例子。当您的类名是Foo
和Bar
时,谈论封装和抽象之类的东西是完全没有意义的。在这里,没有一个合理的答案可以涵盖你的一般准则。如果你想这样做,你需要读一本关于面向对象编程的书。但是在某些情况下,一些实例操作必须应用在它自己的实例和类中,而不是应用在其他类中,以避免违反封装和抽象!这些情况如何?好吧,让我们这样说:如果外部代码确实必须了解内部组件(因为它在您的高级设计中是有意义的),那么尝试封装它可能是错误的。你只是不想把一切都封装起来。毕竟,代码中的某些组件必须相互通信。想象一个没有公共或受保护访问的世界…:)如果有许多类彼此嵌套,那么您的解决方案是无效的。我们必须在每个变量中编写一个自定义设置程序。此外,将变量定义为公共变量不仅可以让相关类直接访问它,还可以让不相关的类直接访问它。那怎么办呢?
class Bar {
public:
Foo get_foo()
{
return foo;
}
set_foo(Foo new_foo)
{
// Update foo with new_foo's values
foo = new_foo;
}
private:
Foo foo;
};