为什么从引用中创建共享指针会复制对象?
我打算让一个构造函数接受引用,然后创建指向作为引用传递的对象的指针,并将这些指针存储在一个字段中。然而,由于某种原因,我这样做的方式,正在创建副本,我不知道为什么:
#include <iostream>
#include <vector>
#include <memory>
// the class with the field of pointers
template<class T, class... Types>
class C
{
private:
std::vector<std::shared_ptr<T>> mem; // the field of pointers
public:
C(T& t, Types&... args)
// make pointers to the objects passed by reference and store them in mem
: mem{ std::make_shared<T>(t), std::make_shared<T>(args)... }
{
// to demonstrate that the pointers point to copies, alter one of the objects (subscript operator expected)
(*mem[0])[0] = 10;
// demonstrate the effect on the local copies
std::cout << "vectors in mem:" << "
";
for (const auto& x : mem) {
for (const auto& y : *x) {
std::cout << y << ' ';
}
std::cout << "
";
}
}
};
int main()
{
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 1, 2, 3 };
std::vector<int> v3{ 1, 2, 3 };
// make an object of type C with some vectors to store pointers to in field mem
C<std::vector<int>, std::vector<int>, std::vector<int>> c(v1, v2, v3);
// demonstrate that original vectors are unaltered
std::cout << "original vectors:"<< "
";
for (const auto& y : v1) {
std::cout << y << ' ';
}
std::cout << "
";
for (const auto& y : v2) {
std::cout << y << ' ';
}
std::cout << "
";
for (const auto& y : v3) {
std::cout << y << ' ';
}
std::cout << "
";
}
我在这里错过了什么?复制发生在哪里?为什么?
解决方案
原因是std::make_shared<T>(t)
。make_shared
将调用T
的构造函数,该构造函数接受给定的参数。并通过引用为其赋予T
lValue。
自然会调用复制构造函数。这是一件好事。如果您创建了指向传递给您的对象的共享指针,您的代码可能会是一堆未定义的行为。
我建议您改为通过智能指针接受该参数。它使您的类的用户可以从API本身清楚地了解所有权语义。
相关文章