Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有办法绕开;返回对局部变量的引用;问题_C++ - Fatal编程技术网

C++ 有没有办法绕开;返回对局部变量的引用;问题

C++ 有没有办法绕开;返回对局部变量的引用;问题,c++,C++,我有一个家庭作业练习。我几乎可以肯定,按照他们的要求,这是无法解决的。然而,我很感兴趣的是,你们是否有任何解决下面提到的问题的方法,因为这似乎是经常发生的事情 描述不长,因此我在下面与您分享: 矩阵∈ rn×n是斜对称的,如果它保持S(转置)= −从课堂上的讲课中推导出平方矩阵 斜对称矩阵。使用长度为n(n)的向量− 1) /2以存储 矩阵条目。实施施工人员、类型铸造和适当的 访问系数 问题发生在尝试提供访问时,因为SquareMatrix中定义的虚拟访问方法返回一个引用 const doubl

我有一个家庭作业练习。我几乎可以肯定,按照他们的要求,这是无法解决的。然而,我很感兴趣的是,你们是否有任何解决下面提到的问题的方法,因为这似乎是经常发生的事情

描述不长,因此我在下面与您分享:

矩阵∈ rn×n是斜对称的,如果它保持S(转置)= −从课堂上的讲课中推导出平方矩阵 斜对称矩阵。使用长度为n(n)的向量− 1) /2以存储 矩阵条目。实施施工人员、类型铸造和适当的 访问系数

问题发生在尝试提供访问时,因为SquareMatrix中定义的虚拟访问方法返回一个引用

const double& SquareMatrix::operator()( int j, int k ) const
{
    assert( j >= 0 && j < m );
    assert( k >= 0 && k < n );
    return coeff[ j + k * m ];
}
常量double&SquareMatrix::operator()(int j,int k)常量 { 断言(j>=0&&j=0&&k 但是,我不能返回对未存储变量的引用。下面的代码只是为了演示我的问题。在这种情况下,j>k块显然不起作用

const double& SkewSymmetricMatrix::operator()( int j, int k ) const
{
    assert( j >= 0 && j < size() );
    assert( k >= 0 && k < size() );
    if( j < k )
    {
        const double* coeff = getCoeff();
        return coeff[ j * ( j - 1 ) / 2 + k ];
    }
    else if ( j > k )
    {
        const double* coeff = getCoeff();
        return -coeff[ k * ( k - 1 ) / 2 + j ];
    }
    else
    {
        return const_zero;
    }
}
常量double&SkewSymmetricMatrix::operator()(int j,int k)常量 { 断言(j>=0&&j=0&&kk) { 常数double*coeff=getCoeff(); 返回系数[k*(k-1)/2+j]; } 其他的 { 返回常数为零; } } 对于如何在尽量减少内存使用的同时提供适当的访问操作符,您有什么建议吗

  • 存储更少的元素
  • 以及计算未存储的 从实际存储的元素中选择所需的元素

  • 如果您希望
    constdouble&SquareMatrix::operator()(intj,intk)const{…}
    重写一个虚方法,从而不断返回一个
    constdouble&
    ,那么我不知道怎么做

    如果允许您更改签名,则创建

    class ValueAccessor {
      double &value;
      bool is_negated;
     public:
      ValueAccessor& operator=(double other) {
        value = is_negated ? -other : other;
        return *this;
      }
      operator double() const {
        return is_negated ? -value : value;
      }
      ...
    };
    

    ,并从
    operator()(…)

    返回
    ValueAccessor
    。问题需要使用
    n*(n-1)/2
    元素的向量,但它没有指定该向量应包含的元素类型

    矩阵∈ 如果R n×n保持S(转置)=−从课堂上的SquareMatrix类派生出SkewSymmetricMatrix类。使用长度为n(n)的向量− 1) /2以存储矩阵项。执行构造函数、类型转换和适当访问系数

    考虑到我们没有能力更改
    SquareMatrix
    类给出的接口,我们将不得不求助于用技术上符合要求的解决方案来解决这个问题,即使它不符合教授要求的精神(这是不可能的)

    向量的每个元素将包含两个
    值,一个对应于元素
    m_ij
    ,另一个对应于
    m_ji
    (对于
    i
    )。我们可以称之为左元素和右元素:

    struct mirror {
        double left; 
        double right; 
    
        void assignLeft(double val) {
            left = val; 
            right = -val;
        }
        void assignRight(double val) {
            left = -val;
            right = val;
        }
    }; 
    
    我们可以使用类型为
    mirror
    n*(n-1)/2
    元素的向量,并根据请求的索引返回
    成员:

    const double& SkewSymmetricMatrix::operator()( int j, int k ) const
    {
        assert( j >= 0 && j < size() );
        assert( k >= 0 && k < size() );
        if( j < k )
        {
            const mirror* coeff = getCoeff();
            return coeff[ j * ( j - 1 ) / 2 + k ].left;
        }
        else if ( j > k )
        {
            const mirror* coeff = getCoeff();
            return coeff[ k * ( k - 1 ) / 2 + j ].right;
        }
        else
        {
            return const_zero;
        }
    }
    
    常量double&SkewSymmetricMatrix::operator()(int j,int k)常量 { 断言(j>=0&&j=0&&kk) { 常量镜像*coeff=getCoeff(); 返回系数[k*(k-1)/2+j]。右; } 其他的 { 返回常数为零; } }

    莫斯科就是这样。

    评论中的一个想法是使用临时私人会员并返回对其的引用。那真是个坏主意

    如果使用对私有成员的引用,则该值将在下次调用时更改。如果调用方使用:

    const double& val1 = my_square_matrix(2, 1);
    const double& val2 = my_square_matrix(3, 1);
    double sum = val1 + val2;
    
    结果将是
    val2+val2
    ,而不是
    val1+val2
    ,因为引用了错误的值

    但是有两种解决方案可以满足要求:

  • 如果调用圆括号运算符,则实现get方法并引发异常。

  • 创建第二个成员向量,但将其保留为空。始终如果访问不存在的元素,请检查向量(如果为空,请将其大小调整一次为n(n-1)/2,但决不能调整为其他大小!),然后将值写入所需位置。然后,返回对此位置的引用。 只需调整向量的大小一次,因为如果调整大小,它可以分配新内存,因此旧引用将无效


  • 在许多现代64位系统上,
    double&
    使用的内存量与
    double
    相同,因此复制
    double
    在速度和内存使用方面都很好。但是,如果希望调用方能够修改值,则需要返回一个
    double&
    。解决方法是返回一个值,而不是一个引用。将计算值存储在私有类成员中,然后返回对它的引用。@SamVarshavchik:通过将计算值存储在私有类成员中,这将无法按预期工作:
    my_square_矩阵(2,1)=42
    @pts这是一个常量引用。这不起作用,因为该类正在重写另一个类中的虚拟方法,并且提问者无法控制基类方法的签名。除非试图证明设计拙劣的缺陷,否则我永远不会分配这样的问题。如果我分配了这样一个问题,这个解决方案将被标记为不正确,因为它是我的