英文:
How to add derived struct elements to a vector without using pointers?
问题
I'm working off of someone's code. There is a vector of struct P
(Segment
). I want to have different types of P
. Therefore I defined struct P2 : P
. But, since Segment
takes just P
and not P*
, I cannot add element of type P2
to the Segment
and use dynamic_cast
since it will create a new element of type P and copy just i
and I lose the name
information.
我正在使用别人的代码。有一个名为 P
的结构体向量(Segment
)。我想要有不同类型的 P
。因此,我定义了 struct P2 : P
。但是,由于 Segment
只接受 P
而不是 P*
,我无法将类型为 P2
的元素添加到 Segment
中并使用 dynamic_cast
,因为它将创建一个新的类型为 P
的元素,只复制 i
,而我会丢失 name
信息。
What are my options here? Do I just have to change vector<P>
to vector<P*>
and adjust the code everywhere it's being used or create my own type Segment vector<P*>
and use where I need it?
在这种情况下,我有哪些选择?我只需要将 vector<P>
更改为 vector<P*>
并在使用它的地方进行代码调整,还是需要创建自己的类型 Segment vector<P*>
并在需要时使用?
Also, why it was used vector<P>
and not vector<P*>
from the beginning since the vector can have hundreds and even thousands of elements?
另外,为什么一开始使用 vector<P>
而不是 vector<P*>
,尽管向量可以包含数百甚至数千个元素?
英文:
I'm working off of someone's code. There is a vector of struct P
(Segment
). I want to have different types of P
. Therefore I defined struct P2 : P
. But, since Segment
takes just P
and not P*
, I cannot add element of type P2
to the Segment
and use dynamic_cast
since it will create a new element of type P and copy just i
and I lose the name
information.
What are my options here? Do I just have to change vector<P>
to vector<P*>
and adjust the code everywhere it's being used or create my own type Segment vector<P*>
and use where I need it?
Also, why it was used vector<P>
and not vector<P*>
from the beginning since the vector can have hundreds and even thousands of elements?
struct P
{
int i;
P(int i2) : i(i2) {}
}
struct P2 : P
{
string name;
P2(string name2, int i) : P(i), name(name2) {}
}
struct P3 : P
{
...
}
using Segment = vector<P>;
答案1
得分: 2
-
继承/多态性: 如你所建议的,但请使用
std::vector<std::unique_ptr<P>>
,避免在现代 C++ 中使用原始指针,因为通常 vector 拥有这些对象。此外,我会定义一个合理的接口,而不是像你当前的示例中使用P2
。 -
类型安全的联合: 例如,
std::variant<P,P2>
,可以包含两种类型之一。然后你需要进一步定义访问者,专门处理包含的类型。 -
类型擦除: 定义一个新类作为通用接口,并将类映射到它。在最简单的版本中,它只是一个
std::function<std::string()>
,可以捕获类的括号运算符等。可以将其视为无基类的继承。
可能还有其他方法,但这些是我认为最常见的方法之一。
英文:
You can basically use one of the following concepts:
-
Inheritance/Polymorphism: As you suggested, but then please with a
std::vector<std::unique_ptr<P>>
. Using a raw pointer as invector<P*>
is discouraged in modern C++, as the vector usually owns the objects. Moreover, I would then define a reasonable interface -- other than in your current example withP2
. -
Type-safe unions: For example, a
std::variant<P,P2>
, which can contain one of the two types. You then further need to define visitors which act specifically on the contained type. -
Type erasure: define a common interface as a new class and map the classes to it. In the simplest version, it's just a
std::function<std::string()>
which captures, e.g., the parenthesis-operator of the classes. This can be thought of as inheritance without base classes.
There's probably more approaches, but those are imo the most common ones.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论