我为我正在做的一些工作制作了一个稀疏矩阵类。对于稀疏结构,我使用指针,例如int* rowInd = new int[numNonZero]
。对于我写的副本和移动赋值运算符,所有工作正常。
在网上阅读关于移动和复制语义,我切然发现了一种压倒性的观点,即在现代C ++中我可能不应该使用原始指针。如果是这种情况,那么我想修改我的代码以使用向量进行良好的编码实践。
vector<Levels> GetGridLevels(int &n, ... ) { vector<Levels> grids(n); \\ ... Define matrix variables for each Level object in grids ... return grids; }
移动语义会阻止它成为昂贵的副本吗?我会这么认为,但它是包含成员矢量变量的对象的矢量,这似乎很多......
答案 0 :(得分:2)
是的,请使用std::vector<T>
代替原始T *
。
同样是的,编译器会为您生成复制和移动赋值运算符,这些运算符很可能具有最佳性能,因此不要自己编写。如果你想要明确,你可以说你想要生成的默认值:
struct S
{
std::vector<int> numbers {};
// I want a default copy constructor
S(const S&) = default;
// I want a default move constructor
S(S &&) noexcept = default;
// I want a default copy-assignment operator
S& operator=(const S&) = default;
// I want a default move-assignment operator
S& operator=(S&&) noexcept = default;
};
关于你的上一个问题,如果我理解正确,你的意思是return
移动感知类型的值是否有效。是的,它会的。要充分利用编译器的优化,请遵循以下规则:
按值返回(不是const
值,这会阻止移动)。
不要return std::move(x)
,只需return x
(至少如果你的回复类型是decltype(x)
),那么就不要禁止复制省略。
如果您有多个return
语句,return
每个路径上都有相同的对象,以便于命名返回值优化(NRVO)。
std::string
good(const int a)
{
std::string answer {};
if (a % 7 > 3)
answer = "The argument modulo seven is greater than three.";
else
answer = "The argument modulo seven is less than or equal to three.";
return answer;
}
std::string
not_so_good(const int a)
{
std::string answer {"The argument modulo seven is less than or equal to three."};
if (a % 7 > 3)
return "The argument modulo seven is greater than three.";
return answer;
}
对于那些编写移动构造函数和赋值运算符的类型,请确保声明它们noexcept
或某些标准库容器(尤其是std::vector
)将拒绝使用它们。
答案 1 :(得分:1)
n
的向量意味着它将初始化其所有元素,因此您可能更愿意构造一个空向量,然后reserve(n)
,然后push_back
元素。< / LI>
std::vector
开始有效移动。另外,请考虑使用现有的库,例如Eigen,这样您就可以免费获得一些相当优化的例程。
答案 2 :(得分:1)
没有。在99%的情况下,最简单地使用std :: vector将比原始指针更好,更安全,并且在需要手动管理内存的不太常见的情况下,这些类可以使用自定义分配器/解除分配器(用于例如,如果你想使用对齐的内存来使用对齐的SSE内在函数)。如果使用自定义分配器,代码可能比原始指针更复杂,但更易于维护,更不容易出现内存问题。
根据您的其他成员以及您的课程所做的事情,您可能需要实施移动/复制分配/ ctors。但这会更简单。您可能必须自己实现它们,但对于您的向量,您只需要调用相应的运算符/ ctors。代码将简单易读,您不会有段错误/内存泄漏的风险
是的,但移动语义甚至不是必需的。返回值优化将负责优化副本(实际上不会有副本)。但这是编译器特定的,并且不受标准保证。