在派生的 class 构造函数中使用智能指针
using smart pointers in a derived class constructor
开头的问题:(前言:初学c++ oop编程)
我如何构造一个派生的 class、Widget
,这样我就有一个(共享?)指针的向量,根据基 class,其中原始对象 (这样它们仍然是派生的 class) 可以在强制转换和取消引用指针时访问吗?
说我有一个基地 class:
class Component {
public:
int a;
int b;
virtual void rtti(){}; // for run time type information.
explicit Component(int a, int b) { this->a = a; this->b = b;}
}
和两个派生的 classes,
class AComponent:public Component{
public:
using Component::Component;
AComponent(int a, int b) : Component(int a, int b){}
}
class BComponent:public Component{
public:
using Component::Component;
BComponent(int a, int b) : Component(int a, int b){}
}
此外,我有一个多组件(这里仍然是通用的):
typedef shared_ptr<AComponent> AComponentPtr;
typedef shared_ptr<BComponent> BComponentPtr;
class MultiComponent{
public:
vector<AComponentPtr> A_components;
vector<BComponentPtr> B_components;
explicit MultiComponent(vector<AComponentPtr> As, vector<BComponentPtr> Bs){
this->A_components = As;
this->B_components = Bs;
}
}
最后,我有这个组件层次结构的具体用例:
class WidgetComponentA:public AComponent{...}
class WidgetComponentB:public BComponent{...}
class Widget:public MultiComponent{
public:
using MultiComponent::MultiComponent;
Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c)
: MultiComponent(???){
}
}
目前,我在 Widget
中设置了 MultiComponent
class 构造函数,如下所示:
class Widget:public MultiComponent{
public:
using MultiComponent::MultiComponent;
Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c)
: MultiComponent({(AComponentPtr)&a},{(BComponentPtr)&b, (BComponentPtr)&c}){}
}
因为这不会产生编译错误。
然后,我在我的主要方法中构建小部件,如下所示:
main(){
WidgetComponentA a = WidgetComponentA(1,2);
WidgetComponentB b = WidgetComponentB(3,4);
WidgetComponentB c = WidgetComponentB(5,6);
// now, the widget:
Widget widget = Widget(a,b,c);
// however, the pointers within the widget
// do not access valid addresses in memory.
return 0;}
Widget widget
对象中的共享指针未引用内存中的任何有效位置,并且失败,
Attempt to take address of value not located in memory.
最终,我想要做的是让 Widget
以基本 class 共享指针的形式保留各种派生类型的组件列表。
然后,我 运行 class 上的通用模板函数,并且仅将指针转换为特定于小部件的派生 class 小部件特定函数中的指针。
为了安全起见,我正在使用共享指针,因为我运行进入了内存泄漏警告...但是如果有更简单的解决方案...
也许我误解了你的要求,但如果你想处理共享所有权的对象,那么你必须将它们设置为:
main()
{
auto a = std::make_shared<WidgetComponentA>(1,2);
auto b = std::make_shared<WidgetComponentB>(3,4);
auto c = std::make_shared<WidgetComponentB>(5,6);
// now, pass the shared stuff to widget:
Widget widget = Widget(a,b,c); // make sure that Widget has
// such constructor that accepts
// the shared pointers
return 0;
}
正如我在评论中所建议的,也许 polymorphic approach 会更容易...
class MultiComponent{
public:
typedef std::vector<std::shared_ptr<Component>> components_vec;
components_vec components;
MultiComponent(components_vec& cv){
components = cv;
}
}
class Widget: public MultiComponent {
public:
Widget(MultiComponent::components_vec& cv)
: MultiComponent(cv){}
}
您可以将指向 Component
的后代的指针转换为 Component*
的后代,然后将它们存储在一起。
然后,或许可以定义一个 virtual void Component::display() = 0
来强制继承者根据您的需要定义某种行为。
开头的问题:(前言:初学c++ oop编程)
我如何构造一个派生的 class、Widget
,这样我就有一个(共享?)指针的向量,根据基 class,其中原始对象 (这样它们仍然是派生的 class) 可以在强制转换和取消引用指针时访问吗?
说我有一个基地 class:
class Component {
public:
int a;
int b;
virtual void rtti(){}; // for run time type information.
explicit Component(int a, int b) { this->a = a; this->b = b;}
}
和两个派生的 classes,
class AComponent:public Component{
public:
using Component::Component;
AComponent(int a, int b) : Component(int a, int b){}
}
class BComponent:public Component{
public:
using Component::Component;
BComponent(int a, int b) : Component(int a, int b){}
}
此外,我有一个多组件(这里仍然是通用的):
typedef shared_ptr<AComponent> AComponentPtr;
typedef shared_ptr<BComponent> BComponentPtr;
class MultiComponent{
public:
vector<AComponentPtr> A_components;
vector<BComponentPtr> B_components;
explicit MultiComponent(vector<AComponentPtr> As, vector<BComponentPtr> Bs){
this->A_components = As;
this->B_components = Bs;
}
}
最后,我有这个组件层次结构的具体用例:
class WidgetComponentA:public AComponent{...}
class WidgetComponentB:public BComponent{...}
class Widget:public MultiComponent{
public:
using MultiComponent::MultiComponent;
Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c)
: MultiComponent(???){
}
}
目前,我在 Widget
中设置了 MultiComponent
class 构造函数,如下所示:
class Widget:public MultiComponent{
public:
using MultiComponent::MultiComponent;
Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c)
: MultiComponent({(AComponentPtr)&a},{(BComponentPtr)&b, (BComponentPtr)&c}){}
}
因为这不会产生编译错误。
然后,我在我的主要方法中构建小部件,如下所示:
main(){
WidgetComponentA a = WidgetComponentA(1,2);
WidgetComponentB b = WidgetComponentB(3,4);
WidgetComponentB c = WidgetComponentB(5,6);
// now, the widget:
Widget widget = Widget(a,b,c);
// however, the pointers within the widget
// do not access valid addresses in memory.
return 0;}
Widget widget
对象中的共享指针未引用内存中的任何有效位置,并且失败,
Attempt to take address of value not located in memory.
最终,我想要做的是让 Widget
以基本 class 共享指针的形式保留各种派生类型的组件列表。
然后,我 运行 class 上的通用模板函数,并且仅将指针转换为特定于小部件的派生 class 小部件特定函数中的指针。
为了安全起见,我正在使用共享指针,因为我运行进入了内存泄漏警告...但是如果有更简单的解决方案...
也许我误解了你的要求,但如果你想处理共享所有权的对象,那么你必须将它们设置为:
main()
{
auto a = std::make_shared<WidgetComponentA>(1,2);
auto b = std::make_shared<WidgetComponentB>(3,4);
auto c = std::make_shared<WidgetComponentB>(5,6);
// now, pass the shared stuff to widget:
Widget widget = Widget(a,b,c); // make sure that Widget has
// such constructor that accepts
// the shared pointers
return 0;
}
正如我在评论中所建议的,也许 polymorphic approach 会更容易...
class MultiComponent{
public:
typedef std::vector<std::shared_ptr<Component>> components_vec;
components_vec components;
MultiComponent(components_vec& cv){
components = cv;
}
}
class Widget: public MultiComponent {
public:
Widget(MultiComponent::components_vec& cv)
: MultiComponent(cv){}
}
您可以将指向 Component
的后代的指针转换为 Component*
的后代,然后将它们存储在一起。
然后,或许可以定义一个 virtual void Component::display() = 0
来强制继承者根据您的需要定义某种行为。