You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中使用代理类实现矩阵切片赋值失效问题求助

Why Your Matrix Slice Assignment Isn't Working (And How to Fix It)

Let's break down exactly why your A(1, 1, 3, 3) = B assignment isn't modifying matrix A, then walk through the fixes.

The Core Issue: SubMatrix Is Modifying a Copy, Not the Original Matrix

The biggest problem is in your SubMatrix class: its _matrix member is a value type (Matrix<T>) instead of a reference to the original matrix. When you call A(1, 1, 3, 3), the SubMatrix constructor creates a full copy of A and stores it in _matrix. Any changes you make to this copy have zero effect on the original A matrix—this is why your output still shows all 1s.

Secondary Issues

There are a couple of other problems that would cause bugs even if you fixed the reference issue:

  1. Missing const correctness: Your slice function and SubMatrix::operator= take non-const references, which prevents you from using const matrices or temporary objects.
  2. No boundary checks: Your slice function doesn't verify if the requested slice fits within the matrix bounds, or if the source matrix matches the slice size—this could lead to undefined behavior.
  3. Inefficient copy logic: The original Matrix::operator= uses a manual loop instead of leveraging standard library utilities like std::copy.

Step-by-Step Fixes

1. Modify SubMatrix to Hold a Reference to the Original Matrix

Change the _matrix member to a reference, so operations affect the original matrix instead of a copy:

template <typename T>
class SubMatrix
{
    size_t _i, _j, _p, _q;
    Matrix<T>& _matrix; // Store a reference to the original matrix, not a copy

public:
    // Initialize the reference in the member initializer list
    SubMatrix(const size_t i,
              const size_t j,
              const size_t p,
              const size_t q,
              Matrix<T>& matrix) : _i(i),
                                   _j(j),
                                   _p(p),
                                   _q(q),
                                   _matrix(matrix) {}

    // Use const reference for the assignment parameter to support const matrices
    SubMatrix<T>& operator=(const Matrix<T>& matrix)
    {
        _matrix.slice(_i, _j, _p, _q, matrix);
        return *this;
    }
};

2. Fix the Matrix::slice Function

Update slice to use const references for the source matrix, add boundary checks, and clean up the logic:

void slice(const size_t i, const size_t j,
           const size_t p, const size_t q,
           const Matrix<T>& other) // Const reference for the source matrix
{
    // Add boundary checks to prevent out-of-bounds access
    if (i + p > _rows || j + q > _cols) {
        throw std::out_of_range("Slice exceeds matrix bounds");
    }
    if (p != other._rows || q != other._cols) {
        throw std::invalid_argument("Source matrix size doesn't match slice size");
    }

    size_t cont = 0;
    for (size_t ii = i; ii < i + p; ++ii)
    {
        for (size_t jj = j; jj < j + q; ++jj)
        {
            const size_t index = _cols * ii + jj;
            _matrix[index] = other._matrix[cont];
            ++cont;
        }
    }
}

3. Improve Matrix Class Correctness and Efficiency

Fix the copy constructor and assignment operator to use const references, add self-assignment checks, and use standard library functions:

// Updated copy constructor (const reference parameter)
Matrix(const Matrix<T>& other) : _matrix(other._matrix),
                                _rows(other._rows),
                                _cols(other._cols) {}

// Updated assignment operator
Matrix<T>& operator=(const Matrix<T>& other)
{
    // Avoid self-assignment
    if (this == &other) {
        return *this;
    }

    // Resize if the target matrix has a different size
    if (_rows != other._rows || _cols != other._cols) {
        _matrix.resize(other._matrix.size());
        _rows = other._rows;
        _cols = other._cols;
    }

    // Use std::copy for efficient element copying
    std::copy(other._matrix.begin(), other._matrix.end(), _matrix.begin());
    return *this;
}

// Make print a const member function (it doesn't modify the matrix)
void print() const
{
    std::cout << '\n';
    for (size_t i = 0; i < _rows; ++i)
    {
        for (size_t j = 0; j < _cols; ++j)
            std::cout << this->operator()(i, j) << ' ';
        std::cout << '\n';
    }
}

Test the Fixed Code

When you run your main.cpp with these changes, the output will now show the expected slice assignment:

1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 
1 1 1 1 1 

9 9 9 
9 9 9 
9 9 9 

1 1 1 1 1 
1 9 9 9 1 
1 9 9 9 1 
1 9 9 9 1 
1 1 1 1 1 

内容的提问来源于stack exchange,提问作者user12422568

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:31:14