![]() |
|
| Правила Форума редакция от 22.06.2020 |
|
|||||||
|
|
Окажите посильную поддержку, мы очень надеемся на вас. Реквизиты для переводов ниже. |
|
![]() |
|
|
Опции темы | Опции просмотра |
Language
|
|
|
#1
|
|
Неактивный пользователь
Пол:
Регистрация: 20.11.2009
Сообщений: 8
Репутация: 0
|
Когда в С++ создаешь массив n обьектов, то конструктор вызывается n
раз автоматически. Как инициализировать каждый обьект в отдельности? Или, например, в цикле? |
|
|
|
| Реклама: | GigaByte B550M DS3H R2 | интеграция сайта на woocommerce | тонкие сверла 0,4 мм купить | Магазин бытовой техники: купить встроенную газовую духовку - переходи на сайт ТАЙМТВ! | инструкция otec |
|
|
#2
|
|
Постоялец
![]() ![]() ![]() ![]() ![]() Пол:
Регистрация: 05.02.2007
Адрес: Москва
Сообщений: 662
Репутация: 271
|
Чтобы конструктор не вызывался автоматически нужно добавить
перед ним префикс explicit. Такие конструкторы будут вызываться только в явных случаях типа MyClass c1(10,1.5);
__________________
Сергей Сергеевич |
|
|
|
|
|
#3
|
|
Конструктор у объектов С++ вызывается всегда, даже если программист не объявлял его, компилятор сам добавит конструктор по-умолчанию и таки вызовет его
Для инициализации каждого объекта в отдельности, нужно просто объявить пустой конструктор, а всю инициализацию производить в отдельной функции, например init(), start() или что-то в этом роде. Таким образом, можно будет пробежаться в цикле по массиву и вызвать для каждого объекта инициализирующую функцию тогда, когда это будет необходимо. Пример: Код:
class A
{
public:
A() {} //Пустой конструктор
~A();
void init(); //Здесь производим инициализацию
};
int main( int argc, char* argv[] )
{
const size_t array_size = 10;
A a[ array_size ];
for( size_t i = 0; i < array_size; ++i )
{
a.init();
}
return 0;
}
__________________
Хочешь быть счастливым - будь им! (с) Козьма Прутков. Ностальгия — это попытка сравнить наихудшее из настоящего с наилучшим из прошлого. (c) ? |
|
|
|
|
| Сказали спасибо: |
|
|
#4
|
|||||||||||||||||||||||
|
Постоялец
![]() ![]() ![]() ![]() ![]() Пол:
Регистрация: 05.02.2007
Адрес: Москва
Сообщений: 662
Репутация: 271
|
Да, если не объявлял, то создается конструктор по умолчанию, но если объявить конструктор без параметров с префиксом explicit, то он будет использоваться только при явном вызове.
__________________
Сергей Сергеевич |
|||||||||||||||||||||||
|
|
|
|
|
#5
|
|||||||||||||||||||
|
Конструктор в C++ вызывается всегда. Рекомендую откомпилировать этот листинг и посмотреть, что получится: Код:
#include "stdafx.h"
#include <iostream>
class A
{
public:
explicit A()
{
std::cout << "Constructor A" << std::endl;
}
~A()
{
std::cout << "Destructor A" << std::endl;
}
};
int main( int argc, char* argv[] )
{
const size_t array_size = 10;
A a[ array_size ];
return 0;
}
__________________
Хочешь быть счастливым - будь им! (с) Козьма Прутков. Ностальгия — это попытка сравнить наихудшее из настоящего с наилучшим из прошлого. (c) ? Последний раз редактировалось kvm; 24.11.2009 в 01:15.. Причина: очепятка |
||||||||||||||||||||
|
|
|
| Сказали спасибо: |
|
|
#6
|
|
Постоялец
![]() ![]() ![]() ![]() ![]() Пол:
Регистрация: 05.02.2007
Адрес: Москва
Сообщений: 662
Репутация: 271
|
Да, действительно я опростоволосился...
Конструктор без параметров не бывает неявным. Вопрос тогда вопрос, какая польза от explicit. Я один пример придумал: Код:
class C
{
int i;
public:
C(){i=0;}
explicit C(const C &a){i=a.i;}
void set(int n){i=n;}
C& operator=(const C &a){i=a.i;return *this;}
};
int main()
{
C c;c.set(1);
C e(c); // правильно, явно вызван копиконструктор
// C d=c;// ошибка (при инициализации используется копи конструктор)
C d;d=c; // правильно(через operator=)
}
__________________
Сергей Сергеевич |
|
|
|
|
|
#7
|
|
Вообще, использование ключевого слов explicit, const и т.д. позволяет избежать некоторые трудноуловимые ошибки. Однако, на практике, многие софтверные компании не следуют рекомендациям стандарта с++. Только что проверил: на полторы тысячи файлов исходных текстов три ключевых слова explicit
![]() Наиболее наглядный пример использования explicit (лично для меня) выглядит так: Код:
#include <iostream>
class String
{
public:
String() : size_( 0 ), str_( NULL )
{
}
~String()
{
if ( NULL != str_ )
{
delete [] str_;
}
}
String( size_t size )
{
size_ = size;
str_ = new char[ size ];
memset( str_, 0, size_ );
}
private:
size_t size_;
char* str_;
};
int main( int argc, char* argv[] )
{
String a = 10;
return 0;
}
Код:
std::cout << a << std::endl; Чтобы избежать такой ситуации конструктор String( size_t size ) следует объявить explicit, тогда компилятор выдаст ошибку и программисту придётся обратиться к определению класса и разобраться в чём дело. Ваш пример на практике используется для запрещения возвращать объект класса из функции по значению. Допустим, Ваш класс попал к другому программисту и он решил расширить его функционал, добавив функцию сравнения следующим образом: Код:
class C
{
int i;
public:
C(){i=0;}
C(const C &a){i=a.i;}
void set(int n){i=n;}
C& operator=(const C &a){i=a.i;return *this;}
friend C cmp( const C& a, const C& b )
{
C c;
c = b;
if ( a.i >= b.i )
{
c = a;
}
return c;
}
};
![]() Так вот объявление конструктора копирования explicit заставит его немного подумать, так как компилятор выдаст ошибку. И код превратится в нечто такое: Код:
friend const C& cmp( const C& a, const C& b )
{
if ( a.i >= b.i )
{
return a;
}
return b;
}
Код:
class auto_file_handle
{
public:
explicit auto_file_handle( HANDLE handle) : handle_( handle ) {}
~auto_file_handle()
{
if ( INVALID_HANDLE_VALUE != handle_ )
{
::CloseHandle( handle_ );
}
}
HANDLE get() { return handle_; }
private:
HANDLE handle_;
auto_file_handle() {}
};
__________________
Хочешь быть счастливым - будь им! (с) Козьма Прутков. Ностальгия — это попытка сравнить наихудшее из настоящего с наилучшим из прошлого. (c) ? Последний раз редактировалось kvm; 25.11.2009 в 00:03.. Причина: Добавил реальный пример. |
|
|
|
|
| Сказали спасибо: |
![]() |
Похожие темы
|
||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| Кто возьмётся написать прогу (сайт) | Mahor | Веб - Программирование | 11 | 20.11.2010 18:28 |
| Написать прогу для автоматизации ввода данных | vitalymirsky | Программирование | 0 | 28.07.2009 13:39 |
| Можно ли написать такое на delphi? | frostmourne | Delphi | 19 | 28.03.2009 19:08 |
| Надо написать небольшую прогу | Glif | Программирование | 2 | 20.07.2008 09:43 |
| Помогите написать прогу для создания образов CD | xsenocid | Программирование | 1 | 18.10.2007 23:16 |
|
|