我有一个表示点(allPoints)的结构向量。此向量包含给定平面上的所有点集合(在此示例中,它包含四个点)。每个结构都包含一对表示一个点,一个标志的整数,以及另一个包含平面上其他所有点的点向量。
我想要做的是从一个点的首选项列表中选择一个点,更改其标志,并将此更改应用于allPoints向量中的该点。我想我需要参考向量或类似的东西。这是我正在谈论的示例:
#include <iostream>
#include <string>
#include <vector>
#include <utility>
using namespace std;
struct Point {
pair<int,int> p;
vector<Point> prefs;
bool flag = true;
};
void fillVectors(vector<Point> & allPoints);
void printState(vector<Point> & allPoints);
int main()
{
vector<Point> allPoints;
fillVectors(allPoints);
printState(allPoints);
// I want to go into the preference list of any given point, select a point, and change its flag. This change
// should be reflected in the allPoints vector, not just the preferences vector
allPoints[0].prefs[2].flag = false;
printState(allPoints);
// The flags have not changed. If I searh for the point in allPoints, then change the flag, it will change
for(Point p : allPoints)
{
if(p.p == allPoints[0].prefs[2].p) allPoints[0].flag = false;
}
printState(allPoints);
}
void fillVectors(vector<Point> & allPoints)
{
pair<int,int> p1 = make_pair(0,0);
pair<int,int> p2 = make_pair(5,0);
pair<int,int> p3 = make_pair(3,7);
pair<int,int> p4 = make_pair(2,9);
vector<pair<int,int>> coords = {p1, p2, p3, p4};
for(int i = 0; i < coords.size(); i++)
{
Point newPoint;
newPoint.p = coords[i];
allPoints.push_back(newPoint);
}
// Fill the preference lists with every other point (in no particular order)
for(int i = 0; i < allPoints.size(); i++)
{
for(int j = 0; j < allPoints.size(); j++)
{
if(i == j) continue; // Do not put a point in its own preference list
allPoints[i].prefs.push_back(allPoints[j]);
}
}
}
void printState(vector<Point> & allPoints)
{
cout << "Contents of all points:\n";
for(Point p : allPoints)
cout << "point: (" << p.p.first << "," << p.p.second << ")" << " Flagged? -> " << p.flag << "\n";
cout << "~\nContents of each preference vector:\n";
for(Point p : allPoints)
{
cout << "point: (" << p.p.first << "," << p.p.second << ")\tprefs: ";
for(Point q : p.prefs)
cout << "(" << q.p.first << "," << q.p.second << "), ";
cout << "\n";
}
cout << "--------------------\n";
}
在这里,我的allPoints拥有四对。打印状态功能将打印所有点中的每个点及其标志,然后打印每个点的首选项列表。我需要的是每个点的prefs向量在allPoints向量中保存对该点对象的引用。相反,它似乎只是在复制。
我想这样做,以便可以在O(1)时间更改点标志,而不是从首选项中获取点所需的O(n)时间,然后在allPoints中搜索并更改它< / p>
答案 0 :(得分:0)
如果您要共享的状态的唯一部分是flag
,并且一旦创建对象后您不打算更改Point::p
成员的值,则可以将bool flag
替换为std::shared_ptr<bool> flag
以及创建副本时-shared_ptr
将被复制,并保留对象之间共享的值。
struct Point
{
Point(const std::pair<int,int>& value)
: p(value)
{}
Point(const Point&) = default;
Point& operator = (const Point&) = default;
const std::pair<int,int> p;
vector<Point> prefs;
std::shared_ptr<bool> flag = std::make_shared<bool>(true);
};
然后,如果您愿意:
Point pt1({1,2});
auto pt2 = pt1;
std::cout << *pt2.flag << " ";
*pt1.flag = false;
std::cout << *pt2.flag << " ";
由于pt1
和pt2
对象共享相同的bool
,因此输出将为“ 1 0”。
注意:如果const
中没有Point::p
,则可以在创建对象的副本后更改其值-在这种情况下,共享此类对象的flag
是没有意义的。
当然,鉴于所有成员都是公开的,这很容易打破,因此您需要仔细访问flag
。为了使此代码安全-应该使用封装。