是否有可能避免将传递给保存指针的函数复制传递给它的函数?
我有一个类holder
的vector,该向量具有从同一抽象基础类(base
)派生的不同类(例如)的实例(例如)。我将其构建为基础阶级的指针,以支持多态性。通过称为add
的方法添加新实例。呼叫添加
时,新类是在括号内构造的,并且未命名(此机制提供给我,无法更改)。
我不太了解该构建类的寿命是什么,以及在退出添加
后如何防止其破坏。它必须构建,因此是否有一种方法可以保持其活力并持有有效的指针?还是我必须创建一个副本并让通过的临时死亡?
我使用的是C ++ 17,我的类都没有手动分配内存,仅使用STL容器和原始数据类型。我一直在寻找std :: move()
,但是我找不到所需的东西。示例代码:
class Base
{
public:
std::vector<int> vec;
virtual void foo() = 0;
}
class Derived : public Base
{
public:
Derived(int a, int b)
{
vec.push_back(a);
vec.push_back(b);
}
void foo() override;
}
class Holder
{
public:
std::vector<Base*> ptrs;
void add(Base& arg) // What should be the type of arg? (Does not have to be Base&)
{
ptrs.push_back(&arg); // How should I add a pointer to arg into ptrs so that
// arg stays alive after returning from this method?
}
}
int main()
{
Holder h;
h.add(Derived(1, 2)); // this is how add() gets called, I cannot change it
...
}
编辑:要澄清,我可以更改add
的签名和正文,以及vector ptrs
使用的数据类型。我无法更改add
的方式(h.add(derived(1,2));
)。
I have a class Holder
with a vector that holds instances of different classes (e.g. Derived
) derived from the same abstract base class (Base
). I constructed it as a vector of pointers to the base class to support polymorphism. New instances are added to the vector via a method called add
. The new classes are constructed inside the parentheses when calling add
and are not named (this mechanism is supplied to me and cannot be changed).
I do not quite understand what the lifetime of this constructed class is and how can I prevent it from being destructed right after exiting add
. It has to be constructed, so is there a way to keep it alive and hold a valid pointer to it? Or will I have to create a copy and let the passed temporary die?
I am using C++17, none of my classes allocate memory manually, only STL containers and primitive data types are used. I've been looking at std::move()
but I did not find what I needed. Example code:
class Base
{
public:
std::vector<int> vec;
virtual void foo() = 0;
}
class Derived : public Base
{
public:
Derived(int a, int b)
{
vec.push_back(a);
vec.push_back(b);
}
void foo() override;
}
class Holder
{
public:
std::vector<Base*> ptrs;
void add(Base& arg) // What should be the type of arg? (Does not have to be Base&)
{
ptrs.push_back(&arg); // How should I add a pointer to arg into ptrs so that
// arg stays alive after returning from this method?
}
}
int main()
{
Holder h;
h.add(Derived(1, 2)); // this is how add() gets called, I cannot change it
...
}
EDIT: To clarify, I can change the signature and body of add
as well as the data type that vector ptrs
uses. I cannot change the way add
is called (h.add(Derived(1, 2));
).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
main
中,传递的参数是在调用
添加
返回之后被暂时销毁的。您可以存储此值,地址,但是您绝对不能解雇它。如果要确保对象在
holder
的寿命中保持有效,那么您唯一的选择是接管现有对象的所有权或制作拥有您拥有的副本。使用
std :: unique_ptr
将现有对象的所有权,可以使所有权明确。
制作副本
在此处使用移动构造函数在此处无效
编辑
根据更新的答案,这是
holder
我将继续执行的实现:注意:这仅适用于
base
的虚拟破坏者;如果这不是一个选项,则需要保存逻辑,以与对象并肩调用正确的破坏者。您不会阻止创建临时派生的
对象,但至少可以使用隐式创建的移动构造函数的派生
来防止base :: vec
In
main
the parameter passed is a temporary destroyed just after the call to
add
returns. You may store this value, the address, but you must never dereference it.If you want to ensure the the object remains valid for the lifetime of
Holder
your only option is taking over the ownership of an existing object or making a copy you've got ownership of.Taking ownership of an existing object
For this using
std::unique_ptr
would be preferrable to make the ownership clear.Making a copy
Use the move constructor here to void a copy
EDIT
According to the updated answer this is the implementation of
Holder
I'd go with:Note: This only works with a virtual destructor of
Base
; if this isn't an option, you'll need to save logic for invoking the correct destructor alongside the object. You do not prevent the creation of the temporaryDerived
object, but at least it's possible to use the implicitly created move constructor ofDerived
to prevent unnecessary copies of the elements ofBase::vec