我正在编写一个模块化软件,我正在解决接口和内存方面的一些问题。
我有一个Base
类,有一些关于关联和组合的繁重工作,所以我更喜欢在界面中编写一次。问题是避免任何内存泄漏或问题只有我的基类应该能够看到字段。除Base
以外的任何人都不应该修改mFields
列表或释放它包含的指针。
问题是BaseField
将会导出,并且会添加方法,而使用Derived
方法的程序应该直接获取DerivedField
的列表:
class BaseField {} ;
class DerivedField : public BaseField {} ;
class Base {
protected:
unique_ptr<BaseField> & addField(unique_ptr<BaseField> f) ;
const unique_ptr<BaseField> & something() ;
const unique_ptr<BaseField> & something2() ;
const std::list<const unique_ptr<BaseField>> & getFields() ;
private:
std::list<const unique_ptr<BaseField>> mFields ;
}
class Derived : public Base {
public:
unique_ptr<DerivedField> & addField(params) ;
const unique_ptr<DerivedField> & something() ;
const unique_ptr<DerivedField> & something2() ;
const std::list<const unique_ptr<DerivedField>> & getFields() ;
}
所以我的问题是如何获得
const std::list<const unique_ptr<DerivedField>> &
Derived::getFields()
中的Base::getFields()
?{/ p>
编辑:
我想我没有清楚地解释我的问题。我理解@NicolBolas在说什么,我同意他的意见,但并不能真正帮助我,所以让我们这样说:
我的软件应解决不同的问题类型,例如Problem1
Problem2
和Problem3
事实是所有问题都有完全相同的子问题结构,例如SubProblem1
SubProblem2
SubProblem3
因此,为了避免代码重复,我决定编写一个BaseProblem
类和一个BaseSubProblems
,它将为每个问题(例如addSubProblem(BaseSubProblem *)
)重复结构和comon操作。
基本问题不是可实现的,因为受保护的构造函数(它只是为避免代码重复而提供的结构)。 addSubProblem(SubProblem *)
方法也受到保护,因此只有derived
Problem
可以添加SubProblem
因此,创建Problem1
的每个用户都知道Problem1
中包含的所有SubProblem都是SubProblem1
的类型。
实际上,我在std::list<SubProblem *>
中使用BaseProblem
,derived Problem class
通过std::list<SubProblem1 *> Problems1::getSubProblems()
提供访问权限
我希望能够宣布只有BaseProblem
只有SubProbblems
拥有derived Problems
,即使只有SubProblems
知道gridview
的实际类型
我希望这种解释比前一种更好。
答案 0 :(得分:0)
你不能这样做。实际上,您无法像这样实现<{1}}接口的任何。 C ++不会那样工作。
类型Derived
和unique_ptr<Derived>
是完全不相关的类型,只要C ++是可以理解的。您不能将一种类型的值,指针或引用转换或转换为另一种类型。好吧,你可以用指针/引用,但你会得到未定义的行为。 unique_ptr<Base>
也是如此。
您的问题是您似乎想要将引用传递给std::list<T>
。这是一个糟糕的API。如果有人选择unique_ptr
,那么这应该意味着他们是该对象的unique_ptr
。通过将claiming ownership
传递给unique_ptr
,调用者告诉addField
获取该指针的所有权。对于它返回对该指针的引用是违反Base
的唯一所有权概念。
unique_ptr
及其同类应返回裸指针:addField
等。使用裸指针,没有所有权影响。
至于Base*
......好吧,你将不得不想出一个基于裸指针的API来公开这样的列表。也许你应该在内部有一个可以公开的getFields
,或者你可以在vector<Base*>
的迭代器周围创建一个迭代器包装器,它从list
中提取指针。
还应该注意,您使用的这种虚假覆盖语法,派生类将基类成员函数隐藏在使用自己的指针的版本中,通常是糟糕的OOP样式。它需要过多的&#34;向下转换&#34;,这是危险的,并且是建议的。没有什么可以阻止用户在基类中发送不是unique_ptr
的{{1}}内容,并且该类用户本身不应该关心这种方式。< / p>
如果他们必须关心,那么你做错了OOP。