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

如何正确复制包含std::vector成员的Matrix类?

Matrix类拷贝构造函数未正确复制元素问题修复

问题描述

实现了一个以std::vector为底层容器的Matrix类,使用拷贝构造函数复制对象后,复制出的矩阵元素全为0,无法得到预期的与原矩阵相同的0-8整数矩阵。

原始代码

matrix.h

#ifndef MATRIX_H
#define MATRIX_H

#include <vector>
#include <iostream>

template <typename T>
class Matrix
{
private:
    int m_rows;
    int m_cols;
    std::vector<T> m_vector;

public:
    // Constructor
    Matrix(int rows, int cols)
        : m_rows{ rows }, m_cols{ cols }
    { 
        m_vector.reserve(rows * cols);
        std::cout << "Constructor. vector capacity = " << m_vector.capacity() << '\n'; 
    }
    
    // Copy constructor
    Matrix(const Matrix<T>& old)
        : m_rows{ old.m_rows }, m_cols{ old.m_cols }
    {
         m_vector.reserve(old.m_rows * old.m_cols);
         m_vector = old.m_vector;
        std::cout << "Copy constructor. vector capacity = " << m_vector.capacity() << '\n';
    }

    const T& operator()(int row, int col) const
    {
        return m_vector[row * m_cols + col];
    }

    T& operator()(int row, int col)
    {
        return m_vector[row * m_cols + col];
    }
}

#endif // MATRIX_H

main.cpp

#include "matrix.h"

int main()
{
    // Create new matrix and fill
    Matrix<int> matrix(3, 3);

    int count = 0;

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            matrix(i, j) = count++;
        }
    }
    
    // Print new matrix
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            std::cout << matrix(i, j) << ' ';
        }
        std::cout << '\n';
    }
    std::cout << '\n';

    // Copy assignment and print new
    Matrix<int> matrix2(matrix);


    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            std::cout << matrix2(i, j) << ' ';
        }
        std::cout << '\n';
    }
    std::cout << '\n';

    return 0;
}

问题根源

  1. 构造函数的错误使用:构造函数中调用m_vector.reserve(rows * cols)仅为vector预留了内存空间,但vector的size仍为0。后续直接通过operator()赋值时,属于越界访问vector元素,是未定义行为。此时原matrix的vector实际上并没有真正存储这些值(size还是0),只是数据写到了预留的内存区域。
  2. 拷贝构造函数无效:由于原matrix的vectorsize为0,执行m_vector = old.m_vector时,只会复制一个空vector,导致matrix2访问的也是越界位置,输出0或随机值。
  3. 语法错误:类定义结束后缺少分号,会导致编译失败。

修复方案

修改后的matrix.h

#ifndef MATRIX_H
#define MATRIX_H

#include <vector>
#include <iostream>

template <typename T>
class Matrix
{
private:
    int m_rows;
    int m_cols;
    std::vector<T> m_vector;

public:
    // 构造函数:直接初始化vector的size为rows*cols,确保元素可合法访问
    Matrix(int rows, int cols)
        : m_rows{ rows }, m_cols{ cols }, m_vector(rows * cols)
    { 
        std::cout << "Constructor. vector size = " << m_vector.size() 
                  << ", capacity = " << m_vector.capacity() << '\n'; 
    }
    
    // 拷贝构造函数:利用vector的拷贝构造函数直接初始化,无需手动reserve
    Matrix(const Matrix<T>& old)
        : m_rows{ old.m_rows }, m_cols{ old.m_cols }, m_vector(old.m_vector)
    {
        std::cout << "Copy constructor. vector size = " << m_vector.size() 
                  << ", capacity = " << m_vector.capacity() << '\n';
    }

    const T& operator()(int row, int col) const
    {
        return m_vector[row * m_cols + col];
    }

    T& operator()(int row, int col)
    {
        return m_vector[row * m_cols + col];
    }
}; // 补上类定义结束的分号

#endif // MATRIX_H

修复说明

  • 构造函数中通过成员初始化列表直接创建m_vector(rows * cols),让vector的size和capacity都设置为rows*cols,后续赋值操作合法,vector会正确记录元素数量。
  • 拷贝构造函数简化为直接调用vector的拷贝构造函数,自动完成所有元素的复制,无需手动预留空间。
  • 补上类定义后的分号,修复语法错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:25:26