- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想创建一个对象,把对象放到一个vector
中,并且仍然能够通过仅访问 vector
来修改同一对象.但是,我知道当一个对象是 push_back()
到 vector
, 该对象实际上被复制到 vector
中.因此,访问 vector
中的对象只会访问一个相似但不同的对象。
我是 C 语言的初学者,所以我知道我可以创建一个指向对象的指针,并制作一个指针 vector 。例如vector<Object *>
.但是,好像 pointers是discouraged在 C++ 中,和 references are preferred .然而,I cannot make a vector of references .
我只想使用标准库,所以 boost
对我来说是禁区。
我听说过智能指针。但是,看起来好像有多种类型的智能指针。为此目的会不会太过分了?如果智能指针确实是答案,那么我该如何确定使用哪一个?
所以我的问题是:创建对象引用/指针 vector 的标准做法是什么?
换句话说,希望下面的(伪)代码能够工作。
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
class Object
{
public:
int field;
};
vector<Object> addToVector(Object &o)
{
vector<Object> v;
v.push_back(o);
v[0].field = 3; // I want this to set o.field to 3.
return v;
}
int main()
{
Object one;
one.field = 1;
cout << one.field << endl; // 1 as expected
Object &refone = one;
refone.field = 2;
cout << one.field << endl; // 2 as expected
vector<Object> v = addToVector(one);
cout << v[0].field << endl; // 3 as expected
cout << one.field << endl; // I want to get 3 here as well, as opposed to 2.
return 0;
}
最佳答案
I would like to create an object, put the object into a vector, and still be able to modify the same object by accessing only the vector. However, I understand that when an object is
push_back()
to a vector, the object is actually copied into the vector. As a result, accessing the object in the vector will merely access a similar, but different object.
我几乎可以肯定这不是您想要或“应该”想要的。请原谅我直接打开我的答案,但除非你有充分的理由这样做,否则你可能不想这样做。
为此 - 一个带有引用的 vector - 要工作,您必须保证在您持有对它们的引用时被引用的对象不会被移动或破坏。如果您将它们放在 vector 中,请确保 vector 未调整大小。如果您像示例中那样将它们放在堆栈上,那么不要让引用 vector 或其拷贝离开该堆栈帧。如果您想将它们存储在某个容器中,请使用 std::list
(它是迭代器 - 基本上是指针 - 在插入或删除元素时不会失效)。
您已经注意到您不能拥有“真实”引用的 vector 。因此,原因是引用不可分配。考虑以下代码:
int a = 42;
int b = 21;
int & x = a; // initialisation only way to bind to something
int & y = b;
x = y;
b = 0;
在那之后,您从x
获得的值将是21,因为赋值并没有改变引用(绑定(bind)到b
)而是改变被引用的对象, 一个
。但是一个std::vector
explicitly requires这个。
您现在可以着手编写一个围绕指针的包装器,例如...
template<typename T>
struct my_ref {
T * target;
// don't let one construct a my_ref without valid object to reference to
my_ref(T & t) : target(&t) {}
// implicit conversion into an real reference
operator T &(void) {
return *target;
}
// default assignment works as expected with pointers
my_ref & operator=(my_ref const &) = default;
// a moved from reference doesn't make sense, it would be invalid
my_ref & operator=(my_ref &&) = delete;
my_ref(my_ref &&) = delete;
// ...
};
...但是自 std::reference_wrapper
以来这是毫无意义的已经准确地提供了:
int main (int, char**) {
int object = 21; // half of the answer
vector<reference_wrapper<int>> v;
v.push_back(object);
v[0].get() = 42; // assignment needs explicit conversion of lhs to a real reference
cout << "the answer is " << object << endl;
return 0;
}
现在有人可能会争论为什么在指针周围使用像 std::reference_wrapper
这样的包装器也可以直接使用指针。 IMO 指针,具有成为 nullptr
的能力,改变了代码的语义:当你有一个原始指针时,它可能是无效的。当然,您可以假设它不是,或者将其放在注释的某个地方,但最终您会依赖代码无法保证的东西(这种行为通常会导致错误)。
如果您的 vector 元素可以“引用”对象或无效,那么原始指针仍然不是首选(对我而言):当您使用 vector 中的元素时是有效的,那么它所引用的对象实际上是从你的代码中的多个地方引用的;它是共享的。对象的“主要”引用应该是 std::shared_ptr
和 vector 的元素 std::weak_ptr
秒。然后,您可以(线程安全)在需要时获取有效的“引用”(共享指针)并在完成后将其删除:
auto object = make_shared<int>(42);
vector<weak_ptr<int>> v;
v.push_back (object);
// ... somewhere later, potentially on a different thread
if (auto ref = v[0].lock()) {
// noone "steals" the object now while it's used here
}
// let them do what they want with the object, we're done with it ...
最后,请对我的回答持保留态度,其中大部分是基于我的意见(和经验),可能不算作“标准做法”。
关于c++ - 仅使用标准库创建 "Vector of References"的标准实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32105092/
我有这个析构函数,它在运行时产生错误“vector 迭代器不可取消引用”。 gridMatrix 是一个 std::vector * > * > * > * > 我添加了 typename 和 typ
我有一个 vector 的 vector ,比方说 std::vector > my2dArray; 现在我想要一个 vector ,其中包含 my2dArray 中 vector 的大小。手动这看起
假设我有一些 vector :v1、v2、v3 假设我还有一个 vector 来保存这些 vList = {v1, v2, v3} 如果我同步了 (vList),这是否意味着 v1、v2 和 v3 也
我正在创建一个 char 的二维 vector 数组作为类变量,但我在将 vector 添加到 vector 数组中时遇到了麻烦。 我正在使用 C++ 11 标准运行 gcc。 我尝试使用 vecto
如何修改 Vec基于 Vec 中某项的信息没有对向量的不可变和可变引用? 我已尝试创建一个最小示例来演示我的特定问题。在我的真实代码中,Builder struct 已经是其他答案提出的中间结构。具体
这个问题在这里已经有了答案: What is the idiomatic Rust way to copy/clone a vector in a parameterized function? (
在我的程序中,我有一个整数 vector 的 vector 。现在我想从 vector 的 vector 中取出一个 vector 并在另一个 vector 容器中对其进行操作,但是我得到了错误...
我得到一个vector>数据由 OpenCV 提供。由于某些原因(例如偏移/缩放),我需要转换数据 Point至Point2f 。我怎样才能做到这一点? 例如: std::vector > conto
我有一个函数,该函数应使用来自字符串类型的给定 vector vector 中的某些元素初始化来自字符串类型的空 vector vector 。我的语法看起来像这样 std::vector> extr
我得到一个vector>数据由 OpenCV 提供。由于某些原因(例如偏移/缩放),我需要转换数据 Point至Point2f 。我怎样才能做到这一点? 例如: std::vector > conto
这里有很多类似的问题,但我没有真正找到任何可以特别回答我的问题的问题。 我有一个 vector 的 vector 作为类的属性。另一个属性是 bucket_count。我想将 vector 的 vec
如果我像这样创建一个 vector 的 vector : std::vector> myVectorOfVectors; 然后用一些东西填充它: std::vector myVector1; myVe
我正在用 C++ 编写自定义 vector 类。我对这样的代码有疑问: vector vec; vec.push_back(one); vec.push_back(two);
这是我发布的问题 c++ program for reading an unknown size csv file (filled only with floats) with constant (b
vector> a; for (int i=0;i v(i+1); iota(v.begin(),v.end(),1); a.push_back(v); } a.erase(a.beg
也许已经晚了,但我不明白为什么我会得到一个超出此代码范围的 vector 下标: int m = 3; int n = 2; std::vector> path(m, std::vector(n, 0
这个问题真的很奇怪,我似乎找不到任何导致它的原因。 所以这里有一个赋值运算符重载函数,鸟类和哺乳动物都是 vector 。 (下面是类) const Register& Register::opera
我怎么去 std::vector> 只是 std::vector> ?有真正有效的方法吗? 最佳答案 我会做这样的事情: #include #include int main() { //
我正在尝试将这些 vector 中的一些数据写入文本文件。当我运行代码时,它返回运行时错误。 Category、Product、Cart、Customer和Address都是struct 包含每个 g
显然它会因您使用的编译器而异,但我很好奇执行 vector> 时的性能问题与 vector*> ,尤其是在 C++ 中。具体来说: 假设您的外部 vector 已满,您想要开始将元素插入到第一个内部
我是一名优秀的程序员,十分优秀!