#cpp #классы #перегрузка_операторов #конструктор #вектор
Хочу написать конструктор класса, который в качестве параметра принимает статический массив (указатель на 1 элемент) и инициализирует вектор внутри класса этим массивом: class A { public: explicit A(int x[]):v(x,x+sizeof(x)/sizeof(*x)) {} // или (int* x) private: vectorv; }; Не работает... В чём проблема?
Ответы
Ответ 1
Параметр вашего конструктора имеет тип int *. Поэтому выражение sizeof(x)/sizeof(*x) эквивалентно выражению sizeof( int * )/sizeof( int ) И может равняться либо 2, если размер указателя равен, например, 8 байтам, а размер объекта типа int равен 4 байтам, либо 1, если данные размеры совпадают. Лучше объявить два перегруженных конструктора. Первый конструктор может быть определен как A( const int *first, const int *last ) : v( first, last ) {} а второй конструктор может быть определен либо как A( const int *first, size_t n ) : v( first, first + n ) {} либо использовать делегирующий конструктор A( const int *first, size_t n ) : A( first, first + n ) {} Также вы можете объявить шаблонный конструктор, как, например, templateA( const int ( &a )[N] ) : v( a, a + N ) {} Вот демонстрационная программа, в которой показаны все три способа вызова конструкторов класса #include #include struct A { A( const int *first, const int *last ) : v( first, last ) {} A( const int *first, size_t n ) : v( first, first + n ) {} template explicit A( const int ( &a )[N] ) : v( a, a + N ) {} std::vector v; }; int main() { int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; A a1( a, a + sizeof( a ) / sizeof( *a ) ); for ( int x : a1.v ) std::cout << x << ' '; std::cout << std::endl; A a2( a, sizeof( a ) / sizeof( *a ) ); for ( int x : a1.v ) std::cout << x << ' '; std::cout << std::endl; A a3( a ); for ( int x : a1.v ) std::cout << x << ' '; std::cout << std::endl; } Ее вывод на консоль 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 Ответ 2
В параметрах функции, в отличие от объявлений массива, int x[] вырождается в int* x, т.е. ничем не отличается от обычного указателя. (Параметры int x[5] или int x[6] также вырождаются int* x). Поэтому надо использовать шаблон и ссылку на массив. class A { public: templateexplicit A(int (&x)[N]) : v(x, x + N) {} private: vector v; }; Ссылка int (&x)[N] не теряет количество элементов в массиве.
Комментариев нет:
Отправить комментарий