![](/img/trans.png)
[英]C++ std::sort() - Unable to sort a vector of a class type that access member variables
[英]C++ Need to enable class member variables to access an std::vector of instances of another class
我正在開發一個API,它可以讓你繪制簡單的幾何形狀並計算它們的元素。 該項目基於SFML庫。
我有這門課:
#ifndef POINT_H_INCLUDED
#define POINT_H_INCLUDED
#include "stdafx.h"
#include "Helper.h"
class Point : public AbstractShape
{
public:
Point(float x, float y);
Vector getCoords();
sf::VertexArray getShape();
void setLabel(std::string label, int param);
private:
float m_x, m_y, m_R;
std::string m_label;
sf::VertexArray m_shape;
sf::Text m_labelObject;
};
#endif
它繼承自抽象類AbstractShape
,就像其他類似的類Segment
和Triangle
。 我需要這個能夠將不同的形狀添加到單個容器中,以便稍后在一個地方方便地處理它們。
在main
函數中,我聲明容器,然后創建Point
的實例,然后將其push_back
送到容器:
std::vector<AbstractShape*> shapes;
Point* p1 = new Point(100, 50);
p1->setLabel("A", 4);
shapes.push_back(p1);
我認為如果實例在創建實例時可以將自己添加到容器中會更好。 為此, Point
類應該能夠從內部查看容器。 實現這一目標的最佳方法是什么,而不是引入太多與Point
類的耦合?
要將自身添加到容器中, Point
需要與容器耦合。 將兩者結合起來似乎是一個壞主意: 為什么Point
應該知道關於std::vector
任何內容 ?
如果您經常在代碼中使用此模式,最好定義一個函數來實例化並將該點添加到容器中:
template<typename T=std::vector<Point*>>
Point *makePoint(int x, int y, T container) {
Point *p = new Point(x, y);
container.push_back(p);
return p; // so we can set other properties easily
}
或者創建另一個封裝點集的Context
類:
template <typename T=std::vector<Point*>>
class Context {
T container;
public:
Point* addPoint(int x, int y) {
Point *p = new Point(x, y);
container.push_back(p);
return p;
}
};
此外,您可能希望使用shared_ptr
或unique_ptr
來避免內存泄漏,盡管這可能會使繼承性變得有點混亂。
這是Ideone的完全WME和第二個選項:
#include <iostream>
#include <vector>
using namespace std;
class Point {
public:
Point (int x, int y) {}
};
template <typename T=std::vector<Point*>>
class Context {
T container;
public:
Point* addPoint(int x, int y) {
Point *p = new Point(x, y);
container.push_back(p);
return p;
}
};
int main() {
Context<> c;
c.addPoint(1, 2);
return 0;
}
我認為如果實例在創建實例時可以將自己添加到容器中會更好。
這是你的決定,但要三思而后行 - 在大多數情況下,最好保持對象盡可能簡單。 如果您只需要簡化代碼,可以這樣做:
你可以創建外部構造函數 ,類似於std :: make_share和std :: make_tuple :
這將使您能夠致電:
construct<Point>(container, 1, 2);
construct<Line>(container, 1, 2, 3, 4);
它將構建Point / Line並將其放入容器中
完整代碼:
#include <iostream>
#include <vector>
using namespace std;
struct AbstractShape
{
virtual std::ostream& dump(std::ostream&) = 0;
};
struct Point : AbstractShape
{
Point(float x, float y) : x(x), y(y) {}
virtual std::ostream& dump(std::ostream& o) override
{
return o << "P[" << x << ":" << y << "]";
}
float x, y;
};
struct Line : AbstractShape
{
Line(float x1, float y1, float x2, float y2) : x1(x1), y1(y1), x2(x2), y2(y2) {}
virtual std::ostream& dump(std::ostream& o) override
{
return o << "L[" << x1 << ":" << y1 << "," << x2 << ":" << y2<< "]";
}
float x1, y1, x2, y2;
};
template<typename Object, typename Container, typename ...Args>
Object* construct(Container& c, Args... args)
{
Object* res = new Object(args...);
c.push_back(res);
return res;
}
int main() {
std::vector<AbstractShape*> container;
construct<Point>(container, 1, 2);
construct<Line>(container, 1, 2, 3, 4);
for (auto s : container)
s->dump(std::cout) << std::endl;
return 0;
}
輸出:
P[1:2]
L[1:2,3:4]
我絕對建議使用std :: unique_ptr而不是原始指針
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.