【发布时间】:2020-04-25 01:47:34
【问题描述】:
我正在尝试存储对继承自外部类中 std::set 内的嵌套抽象基类的对象的引用。
让我先给你看一下代码,因为我认为这更清楚:
Class.h 接口:
#ifndef Class_H_
#define Class_H_
#include <set>
#include <memory>
class Class
{
public:
class AbstractBase;
private:
std::set< std::shared_ptr<AbstractBase>> set;
public:
Class();
~Class();
void add(AbstractBase& object);
};
#endif
Abstract.h 接口:
#ifndef ABSTRACT_H_
#define ABSTRACT_H_
#include "Class.h"
class Class::AbstractBase
{
friend class Class;
public:
virtual ~AbstractBase();
private:
virtual void foo(int in) = 0;
};
#endif
Derived.h 接口:
#ifndef DERIVED_H_
#define DERIVED_H_
#include "Class.h"
#include "AbstractBase.h"
class Derived : private Class::AbstractBase
{
public:
~Derived() override;
private:
void foo(int in) override;
};
#endif
add.cc 实现:
#include "Class.h"
#include "AbstractBase.h"
void Class::add(AbstractBase& object)
{
// create a shared pointer to object
// and insert it in the set
set.insert(std::make_shared<AbstractBase>(object)); // <-- this is where it fails
}
所以我会有多个不同的派生对象,它们都继承自AbstractBase,它们需要一起存储在std::set 容器中。
由于纯虚函数,编译失败。起初,我没有使用std::shared_ptr,并认为这是失败的原因,我发现this SO答案建议使用std::shared_ptr。我仍然在Class::add 中遇到编译错误,因为AbstractBase::foo 是纯的,但我认为std::shared_ptr 可以解决这个问题?
我发现了类似的问题,但没有任何东西可以帮助我解决我的具体问题。有人可以向我解释我做错了什么吗?
谢谢。
编辑:哇!感谢您提供的信息丰富的答案,我需要一些时间来彻底理解它们,看看什么最适合我。我会在完成后更新这个问题!
【问题讨论】:
-
“有人可以向我解释我做错了什么吗?”你的
add函数似乎有错误类型的参数(逻辑上)。它应该是add( std::shared_ptr<AbstractBase> obj )。 -
基本上问题是您的
add()方法应该获得传递给它的对象的所有权,尽管在技术上可以通过引用来做到这一点,但这不是一个正确的解决方案。您需要通过传递智能指针来转移所有权。 -
谢谢,我尝试了您建议的不同变体,但这也没有编译。你确定你的建议是对的吗?是的,我还在学习和阅读很多东西:)
-
有哪些变化?将参数类型更改为
std::shared_ptr并直接插入该指针而不使用std::make_shared语句(最好使用std::move) -
@Slava 我会考虑你的建议! @aschepler 我不想创建一个新对象。目的是当某个事件发生时(所以我将容器更改为
std::map<int, std::set<shared_ptr>>)我遍历映射中的对象并调用映射到事件的容器中对象的所有foo()函数。 @Max Langhof 由于上述原因,我需要该集合,两次在容器中放置一个对象没有意义,这就是我选择std::set的原因。
标签: c++ inheritance