我有一個矢量包裝類,旨在簡化多型性:
class Shape
{
public:
Shape(string Name) : name(Name) {}
virtual ~Shape() = default;
string name;
private:
};
class Point : public Shape
{
public:
Point(string Name, float X, float Y) : Shape(Name), x(X), y(Y) {}
float x = 0.0f;
float y = 0.0f;
private:
};
// A vector wrapper for unique ptrs, simplifies polymorphism
template <typename T>
class Vector_UniquePtrs {
public:
// Constructor with no parameters
Vector_UniquePtrs() = default;
// Constructor with initialiser list
Vector_UniquePtrs(std::initializer_list<T> items)
{
m_Items.reserve(items.size());
// fill `m_Items` from the initializer list by creating a unique_ptr from each element
std::transform(items.begin(), items.end(), std::back_inserter(m_Items), [](const T& item) {
return std::make_unique<T>(item);
});
};
// Adds a Polymorphic Item (and returns a raw ptr to it)
// usage: v.Add<sub_class>()
template <class U, class... Args>
T& Add(Args&&... args) {
// Forward args to make_unique
m_Items.emplace_back(std::make_unique<U>(std::forward<Args>(args)...));
// Return a reference
return *m_Items.back();
}
// Adds an Item (and returns a raw ptr to it)
// usage: v.Add() (equivelent to v.Add<base_class>())
template <class... Args>
T& Add(Args&&... args) {
// Forward to Add<U>
return Add<T>(std::forward<Args>(args)...);
}
// Remove item from vector
void Remove(size_t index) {
Assert_IsValid(index);
m_Items.erase(std::next(m_Items.begin(), index));
}
// Access item in vector
T& operator[](size_t index) { Assert_IsValid(index); return *m_Items[index]; } // non-const
const T& operator[](size_t index) const { Assert_IsValid(index); return *m_Items[index]; } // const
// Swaps items[n] and items[n_Next]
void ItemSwap(size_t n, size_t n_Next) {
Assert_IsValid(n);
Assert_IsValid(n_Next);
std::swap(m_Items[n], m_Items[n_Next]);
}
// Gets the number of elements in the vector
size_t Size() const { return m_Items.size(); }
protected:
// The container
std::vector<std::unique_ptr<T>> m_Items;
// Validity function
void Assert_IsValid(int index) { assert(index > -1 && index < (int)Size()); }
};
但是當使用以下命令呼叫時:
Vector_UniquePtrs<Shape> v;
v.Add<Point>("A", 1.0f, 10.0f);
Shape& ref = v[0];
v.Add<Point>("B", 2.0f, 20.0f);
ref = v[1];
Point& pt1 = dynamic_cast<Point&>(ref);
Point& pt2 = dynamic_cast<Point&>(v[1]);
cout << pt1.name << ": " << pt1.x << ", " << pt1.y << endl;
cout << pt2.name << ": " << pt2.x << ", " << pt2.y << endl;
輸出為: B: 1, 10 B: 2, 20
該參考仍然在“思考”它正在查看繼承變數的 v[0] 和基本變數的 v[1] 。有人可以解釋發生了什么以及我應該如何解決這個問題嗎?
謝謝!
uj5u.com熱心網友回復:
您不能重新分配參考。ref = v[1]將 的值復制v[1]到 參考的物件中ref。因為編譯器只知道這ref是一個Shape它呼叫Shape的賦值運算子,因此只復制Shape成員而使成員Point保持不變。
如果您需要更改參考指向的內容,那么您可能需要改用指標。
如果您希望分配以多型方式作業,那么您需要添加一個為您執行此操作的虛擬方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/476404.html
