Динамически выделить стек stdlib? - PullRequest
1 голос
/ 29 февраля 2012

Я пытаюсь использовать стек stdlib в созданном мной классе, но у меня возникают проблемы с его динамическим созданием.

Вот соответствующий код из моего заголовочного файла "matcher.h":

    private:

        stack<char> opens;

и вот созданный мной конструктор, который выделяет только стек:

#include "matcher.h"
using namespace std;
//Creates a matcher object with the default values.
matcher::matcher()
{
    opens = new stack<char>;
}

Я получаю следующую ошибку:

matcher.cpp:19:17: error: no match for ‘operator=’ in ‘((matcher*)this)->matcher::opens = ((*(const std::deque<char, std::allocator<char> >*)(& std::deque<char, std::allocator<char> >())), (operator new(40u), (<statement>, ((std::stack<char>*)<anonymous>))))’

Thisговорит мне, что std::stack не содержит оператора присваивания, что приводит меня к моему вопросу:

Какой метод я должен использовать, чтобы получить стек, который будет сохраняться в моем объекте matcher, еслив нем нет оператора присваивания?

Спасибо, что уделили время.

Ответы [ 5 ]

3 голосов
/ 29 февраля 2012

opens - это объект внутри класса, поэтому его не нужно выделять с помощью new.

Если вы хотите, чтобы он был построен по умолчанию, тогда это произойдет автоматически - вы нене нужно писать какой-либо код, чтобы сделать это.Если все члены класса могут быть сконструированы по умолчанию, тогда вам вообще не нужно писать конструктор по умолчанию для класса.

Если у вас есть член, который не может (или не должен) бытьсоздается по умолчанию, затем вы делаете это в списке инициализатора конструктора, например:

class matcher {
public:
    matcher() :
        number(42) // initialise with a value
    {}             // nothing else to do - "opens" is automatically initialised

private:
    stack<char> opens;
    int number;
};

Используйте new, только когда вам действительно нужен динамически размещаемый объект, и убедитесь, что он будет удален после завершенияс ним - предпочтительно используя RAII , так как зачастую трудно сделать это правильно любым другим способом.Если вы хотите, чтобы он был привязан к времени жизни другого объекта, просто поместите его в этот класс как член и не беспокойтесь о динамическом размещении.

2 голосов
/ 29 февраля 2012

new всегда возвращает указатель на указанный вами тип. opens должно быть stack<char> *.

Но вы уверены, что вам нужно динамически распределять стек? Закрытая переменная-член, которую вы можете создать в конструкторе, редко нуждается в динамическом размещении. Если вы распределяете его динамически, вы должны delete в деструкторе.

1 голос
/ 29 февраля 2012

Нельзя присвоить stack<char>*, то есть то, что возвращает new stack<char>, переменной stack<char>. Вместо этого вы должны использовать следующий конструктор:

// look ma, no need for new!
matcher::matcher()
{
}

и просто положитесь на инициализацию по умолчанию opens. Стек будет соответствующим образом уничтожен, когда ваш matcher объект имеет значение.

1 голос
/ 29 февраля 2012

Вы присваиваете результат new, который будет указателем на стек.Другими словами, вы пытаетесь присвоить стек * стеку.

Во-вторых, почему вы это делаете?Стек все равно будет размещать свои элементы в куче.Нет необходимости в новом.

0 голосов
/ 29 февраля 2012

Здесь как минимум две проблемы.

private:
    stack<char> opens;

Это означает, что у вас либо using namespace std; в заголовке (очень плохая форма), либо вы требуете, чтобы у него был оператор using namespace std; перед включением заголовка (еще хуже).

Другая проблема - непосредственная причина ошибки вашего компилятора. Вы не должны выделять этот стек opens. Чтобы иметь возможность выделить opens, потребуется объявить его как std::stack<char>* opens; - и это тоже то, что вы обычно не хотите делать. С объявлением, как есть, std::stack<char> opens;, переменная уже существует. Это просто нужно построить. Если вы не укажете, как создать объект в списке инициализатора вашего конструктора, по умолчанию будет использоваться конструктор по умолчанию.

...