Как вы можете использовать векторы и int в качестве конструкторов для класса

#c #constructor

#c #конструктор

Вопрос:

Если бы у меня был класс foo, то

 class foo{
   vector <int> vec;
   int someint;

   public:
   foo(number n): someint(n){}


}
  

Как бы я написал конструктор для vector , для class foo ? Более того, я могу использовать:

 int get_someint() const{

  return someint;
}
  

Чтобы вернуть an int , но как насчет векторов?

Ответ №1:

При работе со сложными типами данных обычно лучше всего работать со ссылками или постоянными ссылками, такими как so:

 class A
{
public:
    A()  {}  // default construct of A, v_ is empty

    A(const std::vector<int>amp; source)
      : v_(source)  // construct A, given a vector that is 
                    // copied into v_
    {
    }

    // returns an immutable reference to v_
    const std::vector<int>amp; get_v() const
    {
       return v_;
    }

    // returns a mutable reference to v_
    std::vector<int>amp; get_v()
    {
        return v_;
    }
private:
    std::vector<int> v_;
};
  

Пример использования:

 A a_no_vec;  // A has an empty vector v_

std::vector<int> src;

src.push_back(16);
src.push_back(19);

A a_with_vec(src);  // A has a vector that is a copy of src
  

Комментарии:

1. Ваш конструктор должен принимать source по ссылке. Вы создаете ненужную копию.

2. @OscarKorz Если бы я хотел распечатать вектор с помощью cout, использовал бы я cout << a_with_vec.get_v() << ‘n’ ?

3. Теоретически да. STL не предоставляет operator<<(ostreamamp;, const vector<T>amp;) , поэтому, если вы его не написали, нет.

4. @OscarKorz Тогда как я могу распечатать вектор, используя STL, также используя a_no_vec.push_back(10); похоже, не работает, потому что это не функция-член. Это имеет смысл, но я подумал, что я мог бы использовать функции-члены <vector>, включая его? Спасибо.

5. @cody a_no_vec — это не a vector , это an A . Попробуйте a_no_vec.get_v().push_back(10); . Что касается печати, вам нужно выполнить итерацию по контейнеру и распечатать значения по отдельности.

Ответ №2:

Вы можете сделать это точно так же. Для всех целей рассматривайте vector<int> как обычную переменную (например, an int , например), чтобы вы могли писать:

 class foo{
   vector <int> vec;
   int someint;

   public:
   foo(number n, vector<int> v): someint(n), vec(v){}
}
  

Он будет скопирован внутри и снаружи, и это может означать много копий памяти. Вот почему для таких больших объектов используется передача по ссылке (либо по указателю, либо по ссылке). Например, чтобы вернуть вектор:

 vector<int> constamp; the_vector()
{ return inner_vector; } // no copy
  

и конструктор также foo(number n, vector<int> constamp; v) будет. Кроме того, если внутренне вам не нужно хранить копию вектора, вы можете использовать указатель или ссылку на этот вектор в качестве члена вместо самой векторной копии, то есть класса, являющегося:

 class foo{
   vector <int>amp; vec;
   int someint;

   public:
   foo(int n, vector<int>amp; v): someint(n), vec(v){}
}
  

(обратите внимание на ссылки). То же самое с указателями.

Комментарии:

1. Спасибо за объяснение. Однако, как бы я использовал тип класса foo в качестве объекта в int main. Если бы мне пришлось указать int, то в main я мог бы написать: foo bar(1); . Это инициализировало бы someint на 1 правильно? Как я могу инициализировать вектор таким же образом, но заполнить его целыми числами?

2. Только в C (не в C 11) нет способа заполнить вектор конструкцией. Вы должны создать его, заполнить его, а затем передать его объекту foo . vector<int> v(2); v[0]=1; v[1]=2; foo my_foo(3,v) .

Ответ №3:

Вам не нужно писать конструктор для вектора. У Vector уже есть свои конструкторы. Также вы можете просто возвращать вектор при возврате вашего int, например

 const std::vector<int> amp; getVec()
{
   return vec;
}