假设我有以下代码
class Car {
public:
string color;
string name;
Car(string c, string n): color(c), name(n){}
}
int main() {
vector<Car> collection1;
vector<Car> collection2;
collection1.emplace_back("black", "Ford");
collection1.emplace_back("white", "BMW");
collection1.emplace_back("yellow", "Audi");
//Question comes here
collection2.push_back(collection1[0]);
}
现在我相信这是collection1[0]
的一个深度复制。
我尝试过使用collection2.emplace_back(move(collection1[0]))
,但是{
我猜对于一个真实物体的向量,这个向量的元素需要实际的内存。因此collection1
的元素必须独立于collection2
的任何元素。我认为最简单的方法是让collection1
和{
简而言之,我想在python中模拟List.append()
方法。在
既然你提到你不喜欢指针,你可以使用引用,但是向量不能存储引用(因为它们不可复制和分配)。但是,
std::reference_wrapper
将引用包装在可复制和可分配对象中。在这样,
^{pr2}$collection2
引用的对象与collection1
引用的对象相同。例如:重要:
请注意,不建议使用这种方式,因为您必须有另一个实体来管理对
collection1
的插入和删除,并对collection2
执行适当的操作。@Serge Ballesta的答案比我的好。使用std::shared_ptr
。试着去爱和拥抱指针:)简短回答: >不能完全模仿C++中的Python <强> >。在
不像Python变量,C++变量是真实对象,而不仅仅是引用(对象),复制对底层对象没有任何作用,因此总是浅的(Python使用类型擦除来允许其变量引用任何可能的对象)。在
在C++中,也可以实现同样的设计。因为只要一个对象的任何引用仍然存在,它就必须保持活动状态,但一旦最后一个引用超出范围,就会被删除(并释放所有内存),所以这样的对象就被共享。处理共享对象的C++方法是通过<强> ^ {< CD1> }。请参见下面的内容,了解为什么它必须是一个类似指针的对象而不是一个类似于引用的对象(例如python变量)。在这样,用C++方式使用C++,你的代码将是
std::shared_ptr<T>
的行为类似于指针,但这与引用非常相似(其语法与指针不同,但实现方式相同)。在注意,在C++中,设计一个与Python变量相同的函数,即^ {< CD1>},但使用^ {CD5>}代替^ {< CD6>},并保证一个有效对象(无空/空引用/指针)是不可能的。原因是
^{pr2}$.
运算符不能重载。例如然后我们可以让代码
工作。这就是C++的原理。这意味着对于间接寻址,应该使用指针。在
设计的结果是,为了允许在两个不同的集合中使用同一个对象,您<>强>必须/s>使用指针或引用集合(谨防,C++不直接允许引用集合;但是,为此创建了{{CD1>})。在
根据您的用例,您可以使用原始指针(如果已经管理了实际对象的生存期),也可以使用内部管理引用计数的智能指针(这里是
std::shared_ptr
),以确保在销毁最后一个shared_ptr
时自动销毁该对象。这离Python对对象的引用不远,前提是您知道最后一个shared_ptr
的销毁实际上会销毁对象(*)。换一种说法,如果你不想让它悬挂起来,就不要保留任何其他的指针或引用。在或者,如果集合不是对称的,也就是说,如果一个集合实际包含所有对象,而另一个集合只包含对前一个集合的对象的引用-引用将是您的最佳选择,而第二个集合可能是
std::vector<std::reference_wrapper<Car>>
。在根据MvG注释添加。在
Python对象和C++ SyrdY-PTR之间可能存在恼人的区别。Python有一个完整的垃圾收集器,它非常聪明,可以检测循环引用,并在没有外部引用时立即销毁循环。示例:a包含对b的引用,其中包含对a的引用。。。在
如果a被删除(或超出范围),b仍将包含整个链
^{pr2}$但如果a和b都被删除(或超出范围),gc将检测到不再有外部ref,并将销毁所有内容。在
遗憾的是,如果您使用^ {CD2>}来管理C++对象的循环,因为它只使用本地REF计数,每个对象都有一个REF到另一个,并且它们永远不会被删除,即使它们将超出范围,这将导致内存泄漏。例如:地狱来了:即使a和b都超出范围,ref计数仍然是1,共享指针永远不会删除它们的对象,没有循环引用通常会发生什么。程序员必须明确地处理这个问题并打破循环(并禁止它发生)。例如,
b.next = make_shared<Node>();
在b超出范围之前就足够了。在相关问题 更多 >
编程相关推荐