Как выделить память внутри этой функции?

У меня есть следующая функция и иерархия классов, так что Multinumber наследуется Pairs, Rational и Complex. Все эти общие функции являются виртуальными в Multinumber. Моя проблема заключается в следующем коде. Как это написано прямо сейчас, переменная newElement выходит за пределы области видимости, когда она добавляется к моему setArray, имеющему тип Multinumber**, и мне нужно найти способ выделить память внутри этой функции. Как ни странно, параметры, которые передаются в функцию, даже если они выводятся в первой строке, всегда пусты, когда я делаю cout<<newElement->tostring(); Кто-нибудь может сказать мне, что здесь не так?

bool Set::addElement(Multinumber* newElement)
{
    bool success = false;
    if(isFull())
    {
        resize();
    }
    if(!isMember(newElement))
    {
        setArray[numElements] = newElement;
        numElements++;
        success = true;
    }
    return success;
}

РЕДАКТИРОВАТЬ: Да, постер правильный, это домашнее задание


person Community    schedule 04.12.2010    source источник
comment
Нам нужно больше кода. Пожалуйста, опубликуйте весь Set класс. Также было бы удобно увидеть реализацию Multinumber.   -  person OJ.    schedule 04.12.2010


Ответы (3)


В реальном мире (я понимаю из вашего предыдущего вопрос, что это для домашнего задания), вы не стали бы реализовывать свой собственный набор. Стандартная библиотека предоставляет эту функциональность (std::set, если вы хотите упорядочить элементы; std::unordered_set, если вы используете C++0x и/или имеете соответствующие расширения и отдаете предпочтение скорости над дополнительными функциями).

Вероятно, вам также следует изучить некоторые классы интеллектуальных указателей.

Это сказало:

В вашем коде newElement не выходит за рамки. Что происходит, так это то, что вам дали указатель на данные вызывающего кода, а вызывающий код затем позволяет указанному объекту выйти за пределы области действия.

Как я ответил на ваш предыдущий вопрос вам нужно использовать "виртуальный клон идиома", чтобы сделать копию.

По сути, вы хотите вызвать new с любым типом переданной, указываемой вещи таким образом, чтобы была сделана копия. Чтобы убедиться, что «копия сделана», естественным было бы использовать конструктор копирования с new, то есть new whatever(my_existing_whatever_instance). Но в C++ конструкторы не могут быть virtual, поэтому мы не можем поместить желаемый тип в вызов new. Вместо этого мы должны подделать его с помощью функции-члена. Поскольку функции-члены могут быть virtual, правильная версия clone ищется в фактическом указанном объекте, который реализован для вызова new с использованием его собственного типа и вызова собственного конструктора копирования. По ссылке приведены подробности.

person Karl Knechtel    schedule 04.12.2010

Чтобы избежать проблем с памятью, замените Multinumber** setArray на std::vector<boost::shared_ptr<Multinumber>> setArray.

person Alexey Malistov    schedule 04.12.2010

Если вам нужно, чтобы он увеличивался, сделайте его типа vector<Multinumber*> и используйте setArray.push_back(newElement).

Вы должны убедиться, что вызывающий объект сохраняет элемент живым, пока жив вектор. Если нет, возможно, добавьте в Multinumber виртуальный метод Clone, который возвращает копию (и подклассы реализуют его). Затем push_back(newElement->Clone()).

person Lou Franco    schedule 04.12.2010
comment
Я предполагаю, что он хочет набор, а не вектор, то есть обеспечивает соблюдение инварианта, что может быть только одно из каждого значения. Кроме того, я предполагаю, основываясь на предыдущих вопросах, что от него требуется реализовать контейнер для домашнего задания. - person Karl Knechtel; 04.12.2010