代码之家  ›  专栏  ›  技术社区  ›  ImaginaryHuman072889

C++在嵌套类中中继成员函数?

  •  2
  • ImaginaryHuman072889  · 技术社区  · 7 年前

    我在一家制造厂工作,该厂使用一个大型C++项目来自动化制造过程。

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

    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;
    
    };
    

    obj1 obj2 public 中的成员 C 类似乎并不不安全,因为 A B 每个类都安全地处理自己成员变量的获取和设置。

    我认为这样做的唯一缺点是 C 调用函数的类需要执行以下操作: obj.obj1.get_a() 而不仅仅是 obj.get_a() 但这似乎比私人 A. B 中的对象实例 C

    我意识到对于这个简单的例子,它并没有太多额外的代码,但对于我公司使用的这个大型项目,它确实增加了 数以万计

    我错过什么了吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   463035818_is_not_an_ai    7 年前

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

    假设您编写了一个函数,该函数对该成员执行某些操作 a A 以及 C . 您的函数可以如下所示:

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

    这不适用于您的 C 因为它有一个不同的接口。

    通常,强制调用代码编写以下内容: obj.obj1.get_a() 不鼓励,因为它揭示了实现细节。如果您曾经改变,例如 然后你的 C 对这种变化没有任何控制。另一方面,如果在原始代码中 更改自 int double C 可以决定是否保留 整数

        2
  •  1
  •   Chris Uzdavinis    7 年前

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

    Law of Demeter / Wikipedia

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

    • O本身
    • m参数
    • O的直接组件对象
    • 一个全局变量,可由O访问,在m范围内

    特别是,一个对象应该避免调用另一个方法返回的成员对象的方法。对于许多使用点作为字段标识符的现代面向对象语言,该定律可以简单地表述为“仅使用一个点”。也就是说,代码a.b.c.Method()违反了a.b.Method()没有违反的法律。