【问题标题】:Decorator Design Pattern, Segmentation fault [closed]装饰器设计模式,分段错误 [关闭]
【发布时间】:2017-10-24 16:25:13
【问题描述】:

我想实现装饰器设计模式。但是,我的代码给了我Segmentation fault 错误。我尝试使用-g 标志对其进行编译,然后使用gdb 对其进行检查。 gdb 仅显示错误在 action 方法内部的某个地方,但我不明白在哪里以及为什么。

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

class CComponent
{
protected:
    int * i_array;
    int i_size;
public:
    CComponent(int i_size)
    {
        this->i_size=i_size;
        i_array= new int[i_size];
        for(int i=0; i<i_size; i++)
        {
            i_array[i]=0;
        }
    }
    virtual int action() = 0;
    ~CComponent()
    {
        delete i_array;
    }
    int get_i_size()
    {
        return i_size;
    }
    int get_array_at(int index)
    {
        return i_array[index];
    }
};

class CConcreteCComponent : public CComponent
{

public:

    CConcreteCComponent(int i_size) : CComponent(i_size) { }

    int action()
    {
        for(int i=0; i<i_size; i++)
        {
            i_array[i] = rand() % 100;
            cout<< i_array[i] << " " << endl;
        }
        return 0;
    }
};

class Decorator : public CComponent
{
protected:
    CComponent * c;
public:
    Decorator(int i_size) : CComponent(i_size)
    {
        c = new CConcreteCComponent(100);
    }
    int action()
    {
        return c->action();
    }
};

class CConcreteDecorator3 : public Decorator
{

public:
    CConcreteDecorator3(int i_size) : Decorator(i_size)
    {
    }

    int action()
    {
        int w = action();
        for(int i=0; i<c->get_i_size(); i++)
            if(c->get_array_at(i) % 2 == 0)
                return w;
        return w + 50;
    }
};

class CConcreteDecorator1 : public Decorator
{
public:
    CConcreteDecorator1(int i_size) : Decorator(i_size)
    {
    }

    int action()
    {
        int w = action();

        if(c->get_array_at(0) == 0 && c->get_array_at(i_size -1) == 0)
            return w + 100;
        return w;

    }

};

class CConcreteDecorator2 : public Decorator
{
public:
    CConcreteDecorator2(int i_size) : Decorator(i_size)
    {
    }

    int action()
    {
        int w = action();

        if(c->get_i_size() > 7)
            return w + 150;
        return w;
    }

};

int main()
{
    Decorator * d = new CConcreteDecorator3(100);
    Decorator * d2 = new CConcreteDecorator1(100);
    Decorator * d3 = new CConcreteDecorator2(100);
    int res;

    res = d->action();
    cout << "res :" << res << endl;

    return 0;
}

【问题讨论】:

  • action() 中调用action() 会发生什么?
  • 当您逐行使用调试器时,您观察到了什么?
  • 旁白:如果您曾经复制或分配CComponent 对象,您将复制i_array 指针,然后将其删除两次。如果需要析构函数,则还需要复制构造函数和复制赋值运算符。 (见The Rule of Three)。或者,如果将i_array 替换为std::vector&lt;int&gt; i_array,则不必担心内存管理问题。

标签: c++ design-patterns decorator


【解决方案1】:

原因是无限回溯。

CConcreteDecorator3 中的 action 方法中,而不是:

int w = action();

您可能应该使用:

int w = Decorator::action();

【讨论】:

  • 是否意味着没有它我有一个递归,不管我不想递归?
  • @mirx 基本上,编译器不知道你想要什么:) 它只是寻找一个合适的函数来调用。如果您不指定在哪里查找该函数,它会看到相同的操作方法并发生递归调用。
  • 好的,我明白了。谢谢!
【解决方案2】:

还有……

  1. 您的装饰器类泄漏。你没有带删除的析构函数。
  2. 使用std::vector&lt;int&gt; 代替int * i_array 和std::unique_ptr 用于CComponent * c; 被认为是一种很好的做法@ 除非无法避免,否则不要使用new/delete。
  3. 您的 CComponent 需要一个虚拟析构函数。 google 多态性和虚析构函数,你会发现很多解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-28
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多