【问题标题】:using smart pointers in a derived class constructor在派生类构造函数中使用智能指针
【发布时间】:2017-07-11 22:01:10
【问题描述】:

问题一开始:(前言:c++ oop 编程新手)

我如何构造一个派生类Widget,这样我就可以在基类中拥有一个(共享?)指针向量,原始对象(使得它们仍然属于派生类)可以在其中在转换和取消引用指针时访问?



假设我有一个基类:

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;}
}

还有两个派生类,

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 Widget:public MultiComponent{
public:
    using MultiComponent::MultiComponent;

    Widget(WidgetComponentA a, WidgetComponentB b, WidgetComponentB c)
        : MultiComponent({(AComponentPtr)&a},{(BComponentPtr)&b, (BComponentPtr)&c}){}
}

因为这不会在编译时产生错误。

然后,我在我的 main 方法中构造小部件,如下所示:

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 对象中的共享指针没有引用内存中的任何有效位置,并且失败,

尝试获取不在内存中的值的地址。



最终,我要做的是让Widget 以基类共享指针的形式保留各种派生类型的组件列表。

然后,我在类上运行通用模板函数,并且只将指针转换为特定于小部件的函数中的特定于小部件的派生类指针。

为了安全起见,我使用共享指针,因为我遇到了内存泄漏警告……但如果有更简单的解决方案……

【问题讨论】:

  • AComponentPtr)&amp;a shared_ptr 实例的范围,该变量很快就会超出范围。一般来说,您的代码在各个级别都被破坏了。例如,您的抽象类具有允许创建临时对象和切片的复制构造函数。
  • 为什么不使用多态性?
  • @VTT 所以我必须在进入构造函数之前创建共享指针向量?
  • @chrisd 我不明白为什么你有单独的向量是所有...
  • 如果你有一些基础的class或者接口,你可以在方法中定义具体的行为...

标签: c++ oop inheritance polymorphism shared-ptr


【解决方案1】:

正如我在 cmets 中建议的那样,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 来强制继承者根据您的需要定义某种行为。

【讨论】:

  • 请问&amp;MultiComponent(components_vec&amp; cv){...} 中做了什么?
  • @chrisd 它以参数cv 作为参考。
【解决方案2】:

也许我误解了你的要求,但如果你想处理共享所有权的对象,那么你必须让它们这样:

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;
}

【讨论】:

    猜你喜欢
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多