C++;在嵌套类中中继成员函数? 我在一家制造工厂工作,使用大型C++项目来自动化制造过程。

C++;在嵌套类中中继成员函数? 我在一家制造工厂工作,使用大型C++项目来自动化制造过程。,c++,class,nested,C++,Class,Nested,我看到到处都有一种做法,似乎使代码变得不必要的长,我想知道使用这种做法是否有特定的原因 下面是一个演示这种做法的简化示例 第一个文件: class A { private: int a; public: int get_a() { return a; } void set_a(int arg) { a = arg; } }; 第二个文件: class B { private: int b; public: int get_b() { r

我看到到处都有一种做法,似乎使代码变得不必要的长,我想知道使用这种做法是否有特定的原因

下面是一个演示这种做法的简化示例

第一个文件:

class A {

private:
   int a;

public:
   int get_a()
   { return a; }

   void set_a(int arg)
   { a = arg; }
};
第二个文件:

class B {

private:
   int b;

public:
   int get_b()
   { return b; }

   void set_b(int arg)
   { b = arg; }
};
第三个文件:

class C {

private:
   A obj1;
   B obj2;

public:
   int get_a()
   { return obj1.get_a(); }

   int get_b()
   { return obj2.get_b(); }

   void set_a(int arg)
   { obj1.set_a(arg); }

   void set_b(int arg)
   { obj2.set_b(arg); }
};
在我看来,设计理念上的一点小小改变就可以大大减少第三个文件中的代码量。大概是这样的:

class C {

public:
   A obj1;
   B obj2;

};
template <typename T>
void foo(T& t) {
    std::cout << " a = " << t.get_a();
}
C
类中拥有
obj1
obj2
be
public
成员似乎并不安全,因为
A
B
类都安全地处理其自身成员变量的获取和设置

我能想到的唯一缺点是,调用函数的
C
类的任何实例都需要执行类似于
obj.obj1.get_a()
的操作,而不仅仅是
obj.get_a()
但这似乎比在
C
类中使用私有
A
B
对象实例,然后手动“中继”它们的所有成员函数要方便得多

我意识到对于这个简单的例子,它并没有太多额外的代码,但对于我公司使用的这个大型项目,它实际上添加了成千上万行代码


我错过了什么吗?

可能有很多原因。一个是:

假设您编写了一个函数,该函数对成员
a
执行某些操作。您希望相同的代码接受
A
C
。您的函数可以如下所示:

class C {

public:
   A obj1;
   B obj2;

};
template <typename T>
void foo(T& t) {
    std::cout << " a = " << t.get_a();
}
模板
空富(T&T){

std::cout它确实添加了一些额外的代码,但重要的是你的接口。类有责任,它拥有的成员是实现细节。如果你公开内部对象并强制用户“获取对象,然后对其进行调用”您将调用方与实现相耦合,而不仅仅是提供一个为用户执行任务的界面。作为类比,[从wikipedia借用]当一个人想要狗走路时,他不会直接命令狗的腿走路;相反,他会命令狗,然后狗会命令它自己的腿

更正式地说,函数的德米特定律要求对象O的方法m只能调用以下类型对象的方法:

  • O本身
  • m参数
  • 在m中创建/实例化的任何对象
  • O的直接组件对象
  • 一个全局变量,可由O访问,在m的范围内
特别是,一个对象应该避免调用另一个方法返回的成员对象的方法。对于许多使用点作为字段标识符的现代面向对象语言来说,这个法则可以简单地表述为“只使用一个点”。也就是说,代码a.b.c.method()违反了a.b.method()不遵守的法则


getter和setter有点异味,但它看起来像是原始开发人员在应用。它有优点和缺点。缺点似乎很明显-添加了大量代码。缺点是什么?(除了我已经提到的,即
obj.obj1.get_a()
obj.get_a()
)没关系……维基百科页面解释得很好。谢谢!你为什么不问问编写代码的人他们是否还在公司?这个问题是合理的,但我能想到数百个好的理由,所以在这里问这个问题没有多大意义。@ChristianHackl我想到了这一点,但大部分代码都是编写的十多年前,一家来自另一个国家的承包公司。即使我有编写代码的人的名字,也不能保证他们在那里工作。即使他们在那里工作,我怀疑他们会急切地回答我的问题。我想继续问下去,因为我认为这样做可能有一个普遍的原因,加上这里的社区是generally擅长以相当快的速度获得答案。一般来说,不鼓励强制调用代码编写类似于obj.obj1.get_a()的内容,因为它揭示了实现细节。哇,好的一点,从来没有这样想过。它确实让使用C类的代码更干净,只是让C类本身看起来有很多功能“头顶"键入代码。无论如何,你在这里的解释很好,正是我想要的。@ImaginaryHuman072889顺便说一句,你帖子中的代码看起来就像我在学校里学到的一样,我花了很多年时间才明白,只有这些代码才真正有理由使用getter和setter。我想知道为什么要使用getter和setter是很重要的ng指南,因为有时你不想遵循它;)