类成员vs函数参数

Class member vs function argument

本文关键字:参数 函数 vs 成员      更新时间:2023-10-16

我有一个关于如何使用面向对象语言(如c++)设计类的问题。在许多情况下,变量既可以赋值给类成员,也可以赋值给函数参数。我举了下面的例子来说明我的观点:

class MyClass
{
public:
  int variable1;
  int variable2:
  MyClass (int vr1, int vr2)
  {
     variable1 = vr1;
     variable2 = vr2;
   }
  bool perform_one_task()
  {
    // do something
    return true;
  }
}

当需要使用该类时,可以使用以下代码:

  int a,b;
  MyClass mine(a,b);
  mine.perform_one_task();

也可以设计一个没有variable1variable2的类。

    class MyClass
    {
    public:
      bool perform_one_task(int variabl1, int variable2)
      {
        // do something
        return true;
      }
    }

在这个类中,variable1variable2不是类的成员,而是函数的参数。我的问题是在哪种情况下第一种设计策略更可取,哪种情况下第二种设计模式更好。给出的例子只假设variable1variable2的结构很小,但是如果它们很大,例如,variable1可能是一个大的数据数组。

当你需要在类实例生命周期的其他地方使用值时,你应该使用第一种模式(成员);否则,如果你只需要在方法中使用值,你应该使用第二种模式

第一个示例是面向对象的(假设perform_one_task()使用了这些变量!)。第二个例子不是,它只是一个用空类包装器包装的函数。

一般来说,面向对象类是打包一些数据和所有相关操作(方法)的一种方式。类在建模真实世界的对象或概念时效果最好。封装在类中的数据受到保护,只能由类提供的操作访问或操作。你通常希望一个类有几个方法以不同的方式操作相同的数据,所以你的例子有点太简单了。

如果您尝试在示例中添加另一个任务,那么您将看到,在第二个示例中,您将最终得到两个不相关的函数,而在第一个示例中,每个任务都能够操作相同的数据。

类实际建模是什么?什么需要封装?谁真正拥有这些数据?

在第一个示例中,成员是实现细节。它们对类的用户/客户端是隐藏的,您可以替换它们并完全更改实现。perform_one_task()方法的客户端不知道这些字段的存在。

。类可以表示二维坐标,成员可以表示X/Y属性。在某些阶段,您可以更改该类以极坐标形式(角度+半径)表示坐标。坐标类的API将保持不变,但实现将从根本上不同。

第二个值纯粹是封装功能。类可以不使用它自己拥有的数据来表示。这并非不合理。您可以合法地实现(例如)一个Calculator类,它只执行计算并封装该功能。将它放在类中的好处是它实现了一些可重用性,并且不受原始源代码的约束。

底线是,你可以编写获取/保存/拥有数据的类,也可以编写不保存状态的类。这两种方法在不同的场景中都是合理的。最根本的问题仍然是谁拥有/控制这些数据。

类成员就是类成员。这些是类对象实例的属性或整个类使用的静态值——因此与类密切相关的值。

你不会在你的类中存储那些不能为你的类建模的值,除非你需要它们(然后它们实际上为你的类建模)。这是不必要的,浪费资源。总是避免不必要的变量。所以基本上:
class MyClass{
public:
  bool perform_one_task(int onlyMethodArg1, int onlyMethodArg2){
    // do something
    return true;
    // onlyMethodArgs are gone since nobody really needs them, we are interested 
    // only in result of calculation
  }
void saveProperties(int prop1, prop2){
    property1=prop1;
    property2=prop2;
} 
private:
    int property1;
    int property2;
};

根据面向对象编程(OOP)的原则,当你开发你的类时,你通常选择什么是对象属性(状态),什么是对象方法(行为)。在这里,方法可以有输入参数。因此,我们可以将您的问题改写为:对象属性和方法参数之间的区别是什么。

对象属性是表征该对象的属性(状态特征),例如3D点由3个坐标表征:x, y, z;圆的特征是中心坐标和半径。

对象方法(行为)是应用于该对象的计算,例如三角形可以有这样的方法,如calculateSquare(), calculatePerimeter(), rotate(angle), move(newX, newY)等

最后方法参数是该方法的输入数据,但它们不是对象属性。例如,2D形状对象可以有rotate(angle)方法,其中angle不是形状对象的属性,而是rotate方法的输入参数,即旋转形状的角度。