Проблема в реализации стека с использованием вектора - PullRequest
0 голосов
/ 16 марта 2011

В классе говорят:

class X
{
     int _top;
     vector<int> _stack;
public:
     X() { } // SOME CONSTRUCTOR
};

Почему конструктор этой формы работает:

X( int capacity )
     : _stack( capacity ), _top( 0 ) { }

Но они не работают:

1

X( int capacity )
{ _stack( capacity );  _top=0; }

2

X( int capacity )
     {_stack = capacity;  _top=0;}

Пожалуйста, объясните.

Ответы [ 4 ]

4 голосов
/ 16 марта 2011

Первый работает, потому что вы инициализируете _stack в списке инициализации, в то время как вторая форма не использует список инициализации.

Прочтите комментарии в этом коде, чтобы понять, что такое список инициализации!

struct sample
{
    int a,b,c; 
    vector<int> _stack;
    sample(int capacity) : _stack(capacity), a(1), b(10), c(100) {} 
           // ^^^^^^^^^^^^^^^^^^^^^ this is called initialization list  

    sample(int capacity, int x) 
    {
       _stack(capacity); //wrong!

       a = b = c = x; // this is called assignment
       //here, inside the constructor body you cannot 
       //initialize member variables, because members has been 
       //constructed and initialized already by the time executions comes here!
    } 
};

По сути, синтаксис _stack(capacity) вызывает конструктор. И конструктор может быть вызван только тогда, когда объект построен. Как только объект создан, вы не можете вызвать конструктор. Во второй форме вы пытаетесь вызвать конструктор, написав _stack(capacity) в теле конструктора, но к этому времени _stack уже создан, поэтому ваш код не работает!

Подробнее о списке инициализации читайте в этом FAQ:

[10.6] Должны ли мои конструкторы использовать «списки инициализации» или «присваивание»?

2 голосов
/ 16 марта 2011

В первой форме вы вызываете конструктор, но не во второй, а в третьей.

В 1 вы звоните vector<T>::operator ()(int), который не определен для vector<T>.

В 2 вам назначается int для vector<T>, который также не определен.

Также имейте в виду, что конструктор std::vector<int>(size_t n) не только резервирует память, но и заполняет вектор нулями n. Если вам нужно установить емкость без фактического добавления каких-либо значений в вектор, позвоните vector<T>::reserve(size_t).

И если само по себе это не является целью реализации стека с помощью vector, в стандартной библиотеке уже доступен контейнерный адаптер std::stack.

stack<int> myStack;

или

stack<int, vector<int> > myVectorBasedStack;
1 голос
/ 16 марта 2011

Эта форма работает, потому что она вызывает конструкторы членов класса.

X( int capacity )
    : _stack( capacity ), //calls vector(int) constructor
    _top( 0 ) // calls int(int) constuctor
{ }

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

X( int capacity )
{ 
    _stack( capacity ); //this is not a constuctor call. But this is vector operator()(int) call. And vector does not have this operator defined.
    //the proper constructor call in this place would be _stack = vector<int>( capacity );
    _top=0;
}

Возможно, вы смешали это с сокращенной формой объявления и вызова конструктора.Если вы объявляете _stack векторным и инициализируете одновременно, вы можете написать:

vector<int> _stack( capacity );

Но это всего лишь краткая формаочевидно, потому что вы не можете просто назначить целое число на вектор

X( int capacity ){ _stack = capacity;  _top=0; }
0 голосов
/ 16 марта 2011

Рабочая форма использует конструктор вектора - это разрешено в списке инициализаторов.

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

Третий не работает, поскольку вектор не реализует оператор присваивания, принимающий int.Может быть изменено на _stack.resize(capacity)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...