Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建一个;参考向量;仅使用标准库_C++_Pointers_Vector_Reference_Standard Library - Fatal编程技术网

C++ 创建一个;参考向量;仅使用标准库

C++ 创建一个;参考向量;仅使用标准库,c++,pointers,vector,reference,standard-library,C++,Pointers,Vector,Reference,Standard Library,我想创建一个对象,将该对象放入向量,并且仍然能够通过仅访问向量来修改相同的对象。但是,我知道当一个对象是push_back()到向量时,该对象实际上被复制到向量。因此,访问向量中的对象只会访问相似但不同的对象 我有C语言的初学者知识,所以我知道我可以创建指向对象的指针,并生成指针向量。e、 g.向量。但是,似乎是在C++中,并且。然而 我只希望使用标准库,因此boost是我的禁区 我听说过智能指针。但是,似乎存在多种类型的智能指针。这样做会不会太过分了?如果智能指针确实是答案,那么我如何确定使用

我想创建一个对象,将该对象放入
向量
,并且仍然能够通过仅访问
向量
来修改相同的对象。但是,我知道当一个对象是
push_back()
向量
时,该对象实际上被复制到
向量
。因此,访问
向量中的对象只会访问相似但不同的对象

我有C语言的初学者知识,所以我知道我可以创建指向对象的指针,并生成指针向量。e、 g.
向量
。但是,似乎是在C++中,并且。然而

我只希望使用标准库,因此
boost
是我的禁区

我听说过智能指针。但是,似乎存在多种类型的智能指针。这样做会不会太过分了?如果智能指针确实是答案,那么我如何确定使用哪一个呢

所以我的问题是:创建对象的引用/指针向量的标准做法是什么?

换句话说,我希望下面的(伪)代码能够工作

#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;
}
#包括
#包括
#包括
使用名称空间std;
类对象
{
公众:
int字段;
};
向量addToVector(对象和对象)
{
向量v;
v、 推回(o);
v[0].field=3;//我希望将o.field设置为3。
返回v;
}
int main()
{
对象一;
1.字段=1;
库特
我想创建一个对象,将该对象放入一个向量,并且仍然能够通过只访问向量来修改同一个对象。但是,我知道当一个对象是
push_back()时
对于向量,对象实际上被复制到向量中。因此,访问向量中的对象只会访问相似但不同的对象

我几乎可以肯定这不是你想要或“应该”想要的。请原谅我直接打开我的答案,但除非你有很好的理由这样做,否则你可能不想这样做

对于这一点-带引用的向量-要工作,您必须保证在保存引用对象时,引用对象不会被移动或破坏。如果向量中有引用对象,请确保该向量未调整大小。如果堆栈中有引用对象,如示例中所示,则不要让引用向量或其副本离开固定框架。如果您想将它们存储在某个容器中,请使用
std::list
(它是迭代器,基本上是指针,在插入或删除元素时不会失效)

<>你已经注意到你不能有一个“真实”的引用向量。因此,引用是不可指派的。考虑下面的代码:

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,因为赋值没有更改引用(绑定到
b
),而是更改了引用对象
a
。但是a改变了这一点

您现在可以开始编写一个围绕指针的包装器,如

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
,而人们也可以直接使用指针。在我看来,指针可以是
nullptr
,它改变了代码的语义:当你有一个原始指针时,它可能是无效的。当然,你可以假设它不是,或者把它放在什么地方在评论中没有提到,但最终你会依赖一些代码无法保证的东西(这种行为通常会导致bug)

如果向量的一个元素可能“引用”一个对象或无效,那么原始指针仍然不是第一选择(对我来说):当使用向量中有效的元素时,它引用的对象实际上是从代码的多个位置引用的;它是共享的然后,对对象的引用应该是a和向量s的元素。然后,您可以(线程安全)在需要时获取有效的“引用”(共享指针),并在完成时删除它:

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 ...
auto object=make_shared(42);
向量v;
v、 推回(物体);
//…稍后的某个地方,可能在另一个线程上
if(auto ref=v[0].lock()){
//在这里使用时,现在没有人“窃取”该对象
}
//让他们对这个物体做他们想做的事,我们已经完成了。。。

最后,请恕我直言,我的回答大多基于我的观点(和经验),可能不算“标准做法”.

指针向量没有问题,只要该向量不需要担心它们指向的对象的生命周期。请使用智能指针向量。我很确定这个问题是重复的。如果是重复的话,很抱歉。我发现的唯一一个类似于我的问题建议使用boost,我希望避免。我如果这确实是重复的,请让我知道。只需使用指针向量。这里不需要智能指针。按一下,您可以使用
std::reference\u wrapper
。解决原始问题的方法是使用
vector::emplace\u back
,这是在C++11中引入的。它从argum在向量中创建一个对象ent列表;例如,
v.emplace\u back()
(参数列表为空)使用默认构造函数(或非类类型的值初始化)在向量中创建新对象。该对象不会被复制或移动到向量中,而是在适当的位置创建的。
std::vector
因为C++11不需要CopySassignable。我认为不能有引用向量的根本原因是不能有指向引用的指针。因此,不可能放置新的引用,迭代器需要研发工作区。
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 ...