#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
— это не avector
, это anA
. Попробуйте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;
}