【问题标题】:Passing class field to member function将类字段传递给成员函数
【发布时间】:2017-06-25 19:32:15
【问题描述】:

我有一个类,它有几个大字段(例如,一些大矩阵),并且有计算这些矩阵的成员函数(当然,矩阵的实际数量更大)

class MyClass  {
protected:
    MatrixType m_11, m_12;
public:
    void compute_m_11(double x);
    void compute_m_12(double x);
}

现在,计算代码非常相似,最复杂的部分是矩阵元素的正确索引(所有涉及的矩阵都相同)。因此,我正在考虑将索引和计算拆分为单独的函数:compute_matrix 函数将执行索引并为矩阵中的每组索引调用 compute_element 函数。这将大大提高代码的可读性并简化调试。

因此,compute_matrix 函数将采用 MatrixType 对我需要填写的类字段的引用以及将执行实际计算的 std::function。我显然想避免编写任何涉及额外复制矩阵的内容,因为它们可能非常大。

所以,问题是:

  1. 将对类字段的引用传递给类成员函数是否合法/有效?
  2. 如果是这样,我是否需要使用std::bind 来传递计算成员函数? compute_elements 函数需要访问MyClass 的一些其他字段。

这就是我的想法:

class MyClass  {
protected:
    MatrixType m_11, m_12;
    double compute_elements_m11(int i, int j, double x);
    double compute_elements_m12(int i, int j, double x);
    void compute_matrix(MatrixType &m, double x, std::function<double(int, int, double) > f);
public:
    void compute_m_11(double x) {compute_matrix(m_11, x, compute_elements_m11);};
    void compute_m_12(double x) {compute_matrix(m_12, x, compute_elements_m12);};
}

【问题讨论】:

  • 与前者相比,后者如何“极大地提高代码可读性和易于调试”让我完全无法理解,但我认为这是一个意见问题。只需 尝试 即可轻松解决合法性问题 (1)。并且 (2) 一旦在 compute_elements_xxx 的主体中(无论你到达那里,bind 或其他),你就可以访问该对象(你最好;你在它的一个成员函数中,this 已经已建立),所以您最好先说访问权限,否则出现严重错误。
  • 提高了可读性和调试的便利性,因为必须以复杂的方式遍历矩阵,并且将其解耦和计算将允许编写只遍历矩阵元素一次的代码。而且计算代码本身很短——如果没有索引部分,它会很容易检查正确性。

标签: c++ c++11 methods


【解决方案1】:

传递成员引用是合法的(并且并不少见),但是您的函数类型是错误的。
你可以使用std::bind,或者你可以使用一个普通的指向成员的指针:

class MyClass  {
protected:
    MatrixType m_11, m_12;
    double compute_elements_m11(int i, int j, double x);
    double compute_elements_m12(int i, int j, double x);
    void compute_matrix(MatrixType &m, double x, double (MyClass::*f) (int, int, double);
public:
    void compute_m_11(double x) {compute_matrix(m_11, x, &MyClass::compute_elements_m11);};
    void compute_m_12(double x) {compute_matrix(m_12, x, &MyClass::compute_elements_m12);};
};

std::bindstd::function 提供了更灵活的实现方式。

【讨论】:

  • 我认为您的意思是函数签名中的MyClass:: 而不是MatrixType::
  • 有趣的部分是您必须在 compute_matrix 实现中调用函数指针。因为 compute_elements_m1[1/2] 不是静态的,你必须指向你当前的对象。所以例如(this-&gt;*f)(1, 2, x)
【解决方案2】:

为什么要将对类字段的引用传递给类成员函数?更好的解决方案是实现一个 get 方法并在 compute_matrix 函数中使用它。您的课程将如下所示:

class MyClass  {
protected:
    MatrixType m_11, m_12;
    double compute_elements_m11(int i, int j, double x);
    double compute_elements_m12(int i, int j, double x);
    void compute_matrix(double x, std::function<double(int, int, double) > f);
public:
    void compute_m_11(double x) {compute_matrix(x, compute_elements_m11);};
    void compute_m_12(double x) {compute_matrix(x, compute_elements_m12);};

    MatrixType& getMatrixType_11( return m_11 );
    MatrixType& getMatrixType_12( return m_12 );

}

【讨论】:

  • "[...] 并在成员函数中使用它"。你指的是哪个成员函数? compute_matrix() 需要知道是阅读 m_11 还是 m_12。仅仅添加一些额外的辅助函数是没有帮助的。
【解决方案3】:

当然,将类属性传递给内部成员函数并不少见,你也可以使用std:bind 来调用成员函数,但问题是你真的需要它还是只使用一个简单的“如果”或类似的东西来决定使用什么?我想说这取决于您的代码路径必须有多少选择才能更好地决定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 2019-09-27
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    相关资源
    最近更新 更多