Компьютерный форум NoWa.cc Здесь может быть Ваша реклама
Правила Форума
редакция от 22.06.2020
Портал .::2BakSa.WS::.
Вернуться   Компьютерный форум NoWa.cc > В помощь вебмастеру > Программирование > Visual C++ / С/C++

Уважаемые пользователи nowa.cc и 2baksa.ws. У нас сложилось тяжёлое финансовое положение. Мы работаем для вас вот уже более 15 лет и сейчас вынуждены просить о помощи. Окажите посильную поддержку проектам. Мы очень надеемся на вас. Реквизиты для переводов ниже.
Webmoney Webmoney WMZ: 826074280762 Webmoney WME: 804621616710
PayPal PayPal_Email E-mail для связи по вопросу помощи
Кошелёк для вашей помощи YooMoney 4100117770549562
YooMoney Спасибо за поддержку!
Ответ
 
Опции темы Опции просмотра Language
Старый 21.11.2009, 00:57   #1
Неактивный пользователь
 
Пол:Мужской
Регистрация: 20.11.2009
Сообщений: 8
Репутация: 0
По умолчанию Можно написать прогу по-другому?

Когда в С++ создаешь массив n обьектов, то конструктор вызывается n
раз автоматически. Как инициализировать каждый обьект в отдельности?
Или, например, в цикле?
Event вне форума
 
Ответить с цитированием Вверх
Здесь может быть Ваша реклама
Здесь может быть Ваша реклама


Реклама: В КНС всегда быстро, выгодно, удобно: Lenovo IdeaPad Slim 3 15IAH8 83ER007QRK - более 50-ти тысяч наименований товаров со склада в Москвеобеденные столы круглыеподставка под цветы напольная деревобак с теном для дачного душаConecte Elementor a WIX


Старый 21.11.2009, 12:57   #2
zss
Постоялец
 
Пол:Мужской
Регистрация: 05.02.2007
Адрес: Москва
Сообщений: 662
Репутация: 271
По умолчанию Re: Можно написать прогу по-другому?

Чтобы конструктор не вызывался автоматически нужно добавить
перед ним префикс explicit.
Такие конструкторы будут вызываться только в явных случаях типа
MyClass c1(10,1.5);
__________________
Сергей Сергеевич
zss вне форума
 
Ответить с цитированием Вверх
Старый 21.11.2009, 18:08   #3
kvm
Неактивный пользователь
 
Аватар для kvm
 
Пол:Мужской
Регистрация: 09.12.2006
Адрес: Москва.
Сообщений: 39
Репутация: 19
Thumbs up Re: Можно написать прогу по-другому?

Конструктор у объектов С++ вызывается всегда, даже если программист не объявлял его, компилятор сам добавит конструктор по-умолчанию и таки вызовет его
Для инициализации каждого объекта в отдельности, нужно просто объявить пустой конструктор, а всю инициализацию производить в отдельной функции, например 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) ?
kvm вне форума
 
Ответить с цитированием Вверх
Старый 23.11.2009, 19:22   #4
zss
Постоялец
 
Пол:Мужской
Регистрация: 05.02.2007
Адрес: Москва
Сообщений: 662
Репутация: 271
По умолчанию Re: Можно написать прогу по-другому?

Цитата:
Сообщение от kvm Посмотреть сообщение
Конструктор у объектов С++ вызывается всегда, даже если программист не объявлял его, компилятор сам добавит конструктор по-умолчанию и таки вызовет его

Да, если не объявлял, то создается конструктор по умолчанию, но если объявить конструктор без параметров с префиксом explicit, то он будет использоваться только при явном вызове.
__________________
Сергей Сергеевич
zss вне форума
 
Ответить с цитированием Вверх
Старый 24.11.2009, 00:04   #5
kvm
Неактивный пользователь
 
Аватар для kvm
 
Пол:Мужской
Регистрация: 09.12.2006
Адрес: Москва.
Сообщений: 39
Репутация: 19
По умолчанию Re: Можно написать прогу по-другому?

Цитата:
Сообщение от zss Посмотреть сообщение
Да, если не объявлял, то создается конструктор по умолчанию, но если объявить конструктор без параметров с префиксом explicit, то он будет использоваться только при явном вызове.

Конструктор в 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;
}
Чтобы не быть совсем уж голословным, приведу цитату из стандарта: статья 12, часть 6, пункт 3 — Инициализация.
Цитата:
12.6.3 Initialization
When an array of class objects is initialized (either explicitly or implicitly), the constructor shall be called for each element of the array, following the subscript order; see 8.3.4. [ Note: destructors for the array elements are called in reverse order of their construction. — end note ]

__________________
Хочешь быть счастливым - будь им! (с) Козьма Прутков.
Ностальгия — это попытка сравнить наихудшее из настоящего с наилучшим из прошлого. (c) ?

Последний раз редактировалось kvm; 24.11.2009 в 00:15.. Причина: очепятка
kvm вне форума
 
Ответить с цитированием Вверх
Старый 24.11.2009, 19:35   #6
zss
Постоялец
 
Пол:Мужской
Регистрация: 05.02.2007
Адрес: Москва
Сообщений: 662
Репутация: 271
По умолчанию Re: Можно написать прогу по-другому?

Да, действительно я опростоволосился...
Конструктор без параметров не бывает неявным.
Вопрос тогда вопрос, какая польза от 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=)
}
__________________
Сергей Сергеевич
zss вне форума
 
Ответить с цитированием Вверх
Старый 24.11.2009, 22:45   #7
kvm
Неактивный пользователь
 
Аватар для kvm
 
Пол:Мужской
Регистрация: 09.12.2006
Адрес: Москва.
Сообщений: 39
Репутация: 19
По умолчанию Re: Можно написать прогу по-другому?

Вообще, использование ключевого слов 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;
выведет 10 в стандартный поток вывода, т.е. a = "10". Однако, это не так.

Чтобы избежать такой ситуации конструктор 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() {}
};
Это вспомогательный класс для того чтобы не забыть освободить хэндл открытого файла. При выходе из области видимости объект будет разрушен и деструктор закроет хэндл. Если бы конструктор не был бы объявлен explicit, то объекту можно было бы присвоить значение другого хэндла, вследсвие чего возникла бы утечка ресурсов.
__________________
Хочешь быть счастливым - будь им! (с) Козьма Прутков.
Ностальгия — это попытка сравнить наихудшее из настоящего с наилучшим из прошлого. (c) ?

Последний раз редактировалось kvm; 24.11.2009 в 23:03.. Причина: Добавил реальный пример.
kvm вне форума
 
Ответить с цитированием Вверх
Ответ


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Кто возьмётся написать прогу (сайт) Mahor Веб - Программирование 11 20.11.2010 17:28
Написать прогу для автоматизации ввода данных vitalymirsky Программирование 0 28.07.2009 13:39
Можно ли написать такое на delphi? frostmourne Delphi 19 28.03.2009 18:08
Надо написать небольшую прогу Glif Программирование 2 20.07.2008 09:43
Помогите написать прогу для создания образов CD xsenocid Программирование 1 18.10.2007 23:16

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 10:23. Часовой пояс GMT +3.


Copyright ©2004 - 2024 2BakSa.WS

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2024, vBulletin Solutions, Inc. Перевод: zCarot
Время генерации страницы 0.18936 секунды с 13 запросами