LINUX.ORG.RU

Ответ на: комментарий от shty

Хм... приватный конструктор - это, видимо, запрет на копирование.

Опасность, как я понимаю, в том, что если в полях класса есть хоть одна ссылка, то при конструкторе копирования по умолчанию скопируется сама ссылка. Т.е. 2 или более объекта будут ссылаться на одну и ту же область памяти. Так?

Чем чревато до delete, думаю, объеснять не надо. Ну а по delete просто будет сегфолт (это кстати хорошо - потому что позволит выявить проблему сразу).

Правильно?

hibou ★★★★★
()
Ответ на: комментарий от a0

> Junior-ы тож талантливые бывают ;) Да и итеративный подход позволяет подправить кривости своевременно, после того как по софтине пройдется QA отдел

Да, после этого интерфейс под mac и под linux как раз сравнивать :) последним пугать детей

namezys ★★★★
()
Ответ на: комментарий от a0

> ну, не скажите... HIG то HIG'ом, но когда видишь такой интерфейс рядом с интерфейсом сделанным рукой мастера понимаешь в чём разница

Junior-ы тож талантливые бывают ;)

бывают, но, увы, реже чем хотелось бы :) да и талант и опыт - это несколько разные категории

Да и итеративный подход позволяет подправить кривости своевременно, после того как по софтине пройдется QA отдел

конечно позволяет, но разница есть и она ощутима :)

shty ★★★★★
()
Ответ на: комментарий от hibou

> Опасность, как я понимаю, в том, что если в полях класса есть хоть одна ссылка, то при конструкторе копирования по умолчанию скопируется сама ссылка.

Совсем не правильно. В корне. Ты думаешь об устройстве объекта - но тебе же не нем не говорили. Значит надо думать о нем, как о черном ящике.

Отсутствие конструктора копировании - это отсутствие семантики копирования (например, у главного объекта приложения). В том числе это отсутвие семантики значения.

А уж там ссылки, указатели - это все проблемы разработчика класса объекта, которые легко решаются.

namezys ★★★★
()
Ответ на: комментарий от shty

Пока сбрил только бороду. Жаль что ее не видно на аватарке.

bioreactor ★★★★★
()
Ответ на: комментарий от hibou

Хм... приватный конструктор - это, видимо, запрет на копирование.

Опасность, как я понимаю, в том, что если в полях класса есть хоть одна ссылка, то при конструкторе копирования по умолчанию скопируется сама ссылка. Т.е. 2 или более объекта будут ссылаться на одну и ту же область памяти. Так?

так, только не забываем что при этом область памяти на которую до копирования ссылки указывал указатель станет безхозной (orphaned) :) то есть до кучи будет утечка памяти

Чем чревато до delete, думаю, объеснять не надо. Ну а по delete просто будет сегфолт (это кстати хорошо - потому что позволит выявить проблему сразу).

ну насчёт того насколько segfault - это хорошо я не знаю, но вот с выявлением могут быть проблемы :) потому как delete имеет обыкновение в деструкторах вызываться и вот Ваш код отработал, началось удаление и, ВНЕЗАПНО, всё падает... если код наверченый - пойди разберись :) не в том смысле что не разберёшься, а в том что время тратится -> скорость разработки dramatically decreases... а теперь если во втором классе какой-то «умный» человек забыл поставить delete то у Вас будет просто течь память, а падать ничего не будет... тоже весело, правда?

и это, заметьте, даже не нюанс, а просто известный всем факт... :) так что пока человек научается писать нормально программы на c++ проходит не один год, это в отличие от пресловутых java, python, c# и иже с ними

shty ★★★★★
()
Ответ на: комментарий от namezys

Отсутствие конструктора копировании - это отсутствие семантики копирования

ну, в отсутствие семантики копирования её компилятор дописывает, но делает это он «очень умно», типа foo = rhs.foo

то есть если foo у нас void* то тупо копируется адрес со всеми вытекающими :)

shty ★★★★★
()
Ответ на: комментарий от shty

В продакшене что только не используется, в том числе языки с более вменяемым синтаксисом. Ты не поверишь, даже скриптовые используются :)

Deleted
()
Ответ на: комментарий от shty

> и это, заметьте, даже не нюанс, а просто известный всем факт... :) так что пока человек научается писать нормально программы на c++ проходит не один год, это в отличие от пресловутых java, python, c# и иже с ними

Ну это то легко лечится shared_ptr-ами, которые однако добавляют оверхеда, особенно в мультитредном окружении. Их вроде бы уже в 0x собираются в std:: включить.

a0
()
Ответ на: комментарий от Deleted

В продакшене что только не используется, в том числе языки с более вменяемым синтаксисом. Ты не поверишь, даже скриптовые используются :)

поверю, поверю, чего не верить то? :)

только вопрос был про другое:

__Местами__ его синтаксис страшнее ядерной войны.

покажи серьёзный язык про который нельзя так сказать

итак? про каждый из языков с которыми мне приходилось сталкиваться вполне можно так сказать :)

shty ★★★★★
()
Ответ на: комментарий от shty

> итак? про каждый из языков с которыми мне приходилось сталкиваться вполне можно так сказать :)

У Objective-C синтаксис достаточно монотонный в плане степени страшности ;) Немного непривычный, но если привыкнуть, то все ок :)

a0
()
Ответ на: комментарий от a0

> и это, заметьте, даже не нюанс, а просто известный всем факт... :) так что пока человек научается писать нормально программы на c++ проходит не один год, это в отличие от пресловутых java, python, c# и иже с ними

Ну это то легко лечится shared_ptr-ами, которые однако добавляют оверхеда,

увы, но да - добавляют и добавляют серьёзно, иначе бы не было смысла в boost:scoped_ptr :) но и scoped_ptr тоже добавляет иначе тогда какой смысл использовать обычные указатели :)

в общем см. stl design :)

особенно в мультитредном окружении.

это вообще отдельная большая песня :)

Их вроде бы уже в 0x собираются в std:: включить.

главное чтобы не было как с std::auto_ptr, что вроде и есть, а юзать всё равно стрёмно :)

shty ★★★★★
()
Ответ на: комментарий от shty

> ну, в отсутствие семантики копирования её компилятор дописывает, но делает это он «очень умно», типа foo = rhs.foo

Чего?

namezys ★★★★
()
Ответ на: комментарий от a0

> Ну это то легко лечится shared_ptr-ами, которые однако добавляют оверхеда, особенно в мультитредном окружении. Их вроде бы уже в 0x собираются в std:: включить.

И тут есть куча подводных камней

namezys ★★★★
()
Ответ на: комментарий от a0

> У Objective-C синтаксис достаточно монотонный в плане степени страшности ;) Немного непривычный, но если привыкнуть, то все ок :)

Ну не скажите. Там можно навородить на define такое

namezys ★★★★
()
Ответ на: комментарий от shty

> увы, но да - добавляют и добавляют серьёзно, иначе бы не было смысла в boost:scoped_ptr :) но и scoped_ptr тоже добавляет иначе тогда какой смысл использовать обычные указатели :)

Вы не правы. Дело как раз в разной семантике указателя

главное чтобы не было как с std::auto_ptr, что вроде и есть, а юзать всё равно стрёмно :)

Это почему стремно?

namezys ★★★★
()
Ответ на: комментарий от namezys

>Сам ты плохой. Отличный и красивый язык. Только он своей архитектурой способствует плохому программирвоанию, но не запрещает программировать хорошо

То, что ты не понимаешь, как С++ плох говорит о тебе с плохой стороны.

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz

> То, что ты не понимаешь, как С++ плох говорит о тебе с плохой стороны.

А может вы так и не научились его готовить?

namezys ★★★★
()
Ответ на: комментарий от Deleted

Тебе привести Lua

oh, yeah baby?

StorageClass = {}
StorageClass_mt = { __index = StorageClass }
function StorageClass.new(classname)

	local new_class = { }
	local new_class_mt = {__index = new_class }

	setmetatable(new_class,StorageClass_mt)

	function new_class.new(...)
		local inst = {classname=classname}
		setmetatable(inst,new_class_mt)

		if(new_class.init)then
			inst:init(...)
		end
		return inst;

	end
	return new_class;
end

и это несмотря на то что lua весьма небольшой изящный язык

хотя я в Lua не большой спец, мог и наваять лисапед с треугольными колёсами и без седла :)

с Ruby на тележке или как?

Ruby не трогал, но уверен что там есть свои «аццкие фокусы» :)

shty ★★★★★
()
Ответ на: комментарий от namezys

> ну, в отсутствие семантики копирования её компилятор дописывает, но делает это он «очень умно», типа foo = rhs.foo

Чего?

шо не так?

shty ★★★★★
()
Ответ на: комментарий от namezys

> Да ну. И на что его заменили?

Ну или может имелось в виду, что выкинут из 0x, как раз заменив на shared_ptr-ы всякие. Этот факт я из книжки Маерса вычитал, честно говоря в детали не вдавался, т.к. сам auto_ptr-ами не пользуюсь, и никому не разрешаю, кроме случаев, когда он используется исключительно для авторелиза обьекта аллокированного в конкретном scope-е, где гарантированно известно, что указать на обьект никуда никогда не передан будет.

Вообще, да, в реализациях STL-я в том-же gcc auto_ptr пока никуда не делся.

a0
()
Ответ на: комментарий от a0

Ну не скажите. А тем же auto_ptr пользуюсь достаточно часто

Точнее у меня почти не когда не бывает указателей без явных владельцев

auto_ptr хорош тем, что не делает ничего лишнего (кроме проверки на разыменовывание нуля)

namezys ★★★★
()
Ответ на: комментарий от namezys

> увы, но да - добавляют и добавляют серьёзно, иначе бы не было смысла в boost:scoped_ptr :) но и scoped_ptr тоже добавляет иначе тогда какой смысл использовать обычные указатели :)

Вы не правы. Дело как раз в разной семантике указателя

простите, но я не очень понял что Вы имеете в виду, поясните пожалуйста

> главное чтобы не было как с std::auto_ptr, что вроде и есть, а юзать всё равно стрёмно :)

Это почему стремно?

Effective STL (Scott Meyers), Item 8 :)

shty ★★★★★
()
Ответ на: комментарий от shty

> Effective STL (Scott Meyers), Item 8 :)

Не буду я на работе щас искать, коротко расскажите, плиз

простите, но я не очень понял что Вы имеете в виду, поясните пожалуйста

сам запутанно сказал.

в общем смысл фразы такой, что очень часто сам объект диктует семантику владения им

namezys ★★★★
()
Ответ на: комментарий от namezys

а :)

ну если компилятор не находит конструктор копии в классе, то он его дописывает туда самостоятельно, но все члены класса копируются простым присваиванием (shallow copy), то есть если у нас есть член класса который является указателем то ему будет присвоен новый адрес и всё... при этом старая область памяти на которую он указывает «утекает», так как на неё уже никто не ссылается, а на область памяти на которую указывала присваиваемая переменная указывают 2 указателя

то есть

before:

ptr1 ----------> mem1

ptr2 ----------> mem2
after:

ptr1 -----+----> mem1
          |
ptr2 -----+      mem2

что будет начать работать с обоими указателями одновременно, надеюсь понятно

равно, надеюсь, понятно что будет если удалить сначала 1-й а потом 2-й указатель :)

shty ★★★★★
()
Ответ на: комментарий от namezys

> Не буду я на работе щас искать, коротко расскажите, плиз

Основной наезд на то, что копирование обьекта модифицирует исходный обьект, и например auto_ptr-ы не затолкать ни в один контейнер, не говоря уже об необходимости очень-очень-очень аккуратно с ними обращаться при копировании обьектов, содержащих auto_ptr-ы мемберами.

a0
()
Ответ на: комментарий от a0

> Основной наезд на то, что копирование обьекта модифицирует исходный обьект

Это да, УГ

и например auto_ptr-ы не затолкать ни в один контейнер

много какие объекты заталкать нельзя

По семантики эксклюзивного владения он вполне хорошо. А вот по семантике копирования УГ

namezys ★★★★
()
Ответ на: комментарий от namezys

> Effective STL (Scott Meyers), Item 8 :)

Не буду я на работе щас искать, коротко расскажите, плиз

если совсем вкратце то корявая реализация владения указателем (и до истерики смешная при копировании)

в общем смысл фразы такой, что очень часто сам объект диктует семантику владения им

если я Вас правильно понял, то суть проблемы с std::auto_ptr в том что он так распоряжается семантикой владения, что лучше его вообще не использовать :)

а использовать либо std::tr1::shared_ptr и std::tr1::weak_ptr либо boost::shared_ptr и boost::scoped_ptr либо как вариант написать свой smart ptr

shty ★★★★★
()
Ответ на: комментарий от namezys

у boost::scoped_ptr нельзя забрать указатель - а иногда хочется (чтоб например передать его наверх)

и не зря... для таких целей используй boost::shared_ptr

shty ★★★★★
()
Ответ на: комментарий от shty

> скомпилил? :)

Да. Для всех элементарных типов были введены «конструкторы» по умолчанию и «конструкторы копирования» (присвоение нуля и присвание элемент)

Ибо в противном случае в шаблонох был бы полный пи...

и не зря... для таких целей используй boost::shared_ptr

Ты же сам говорил о затратности данной штуки. Не всегда это выгодно.

namezys ★★★★
()
Ответ на: комментарий от shty

ЧЯДНТ?

#include <iostream>

using std::cout;

class A
{
public:
        A() { cout << "A created\n"; }
        A(const A&) { cout << "A constr-copied\n"; }
        const A& operator= (const A&) { cout << "A copied\n"; return *this; }
};

class C
{
        A a;
public:
        C() { cout << "C created\n"; }
};

int main()
{
        C c1, c2;
        c1 = c2;
}

$./a.out
A created
C created
A created
C created
A copied

a0
()
Ответ на: комментарий от a0

Кстати, топикстартер, найди проблему в этом коде, давай, покажи ;) Тут есть один очень коварный косяк, который малозначим в случае показать как работает, а в жизни - опасный.

a0
()
Ответ на: комментарий от a0

> const A& operator= (const A&) { cout << «A copied\n»; return *this; }

Рекомендуется позвращаемое занчение не делать const

ибо в С++ конструкция вида ( a = b ) = c иногда применяется

namezys ★★★★
()
Ответ на: комментарий от namezys

> ибо в С++ конструкция вида ( a = b ) = c иногда применяется

Все зависит от контекста, и привычки.

a0
()

Похоже окончательно засцал топикстартер что-то отвечать. Если и ответит, то только «Школоло такое школоло» :) Вопросы проигнорит опять.

a0
()
Ответ на: комментарий от namezys

> скомпилил? :)

Да.

теперь компилим, запускаем и наслаждаемся :)

(требуемые хедеры, надеюсь, подключишь)

class A {
public:

	A() : p() { }

	A(const char* str){
		size_t str_size = sizeof(char*)*strlen(str);
		p = (char*)malloc(str_size);
		strcpy_s(p, str_size, str);
	}

	~A() {
		free(p);
	}

	char* p;
};

void print_value(A a) {
	std::cout << a.p << std::endl;
}

int main(int argc, char** argv[])
{
	A a("pssst");

	print_value(a);

	std::cout << a.p << std::endl;

	return 0;
}
shty ★★★★★
()
Ответ на: комментарий от namezys

> и не зря... для таких целей используй boost::shared_ptr

Ты же сам говорил о затратности данной штуки. Не всегда это выгодно.

ой-вей! то было совсем не про то что «эту штуку» использовать не надо, а о том что надо думать при её использовании :)

shty ★★★★★
()
Ответ на: комментарий от shty

Я же о другом писал. тут же вызов контсркутора копирования

а о том что надо думать при её использовании

в с++ вообще думать надо :)

namezys ★★★★
()
Ответ на: комментарий от a0

ЧЯДНТ?

та Вы сейчас вообще что-то сделали странное :)

мы с namezys разговариваем проблеме сгенерённого компилятором конструктора копии при наличии в данных класса указателей

а к чему Вы кусок кода привели я не знаю, наверное Вы с кем-то другим общались, а ответили почему то на моё сообщение :)

shty ★★★★★
()
Ответ на: комментарий от shty

Вообще неявное побочное действие, особенно не характерное для семантики операции, которую мы делаем, вещь катастрофически опасная

namezys ★★★★
()
Ответ на: комментарий от namezys

Я же о другом писал. тут же вызов контсркутора копирования

эммм... напомню о чём речь шла

dialogue

- если компилятор не находит конструктор копии в классе, то он его дописывает туда самостоятельно, но все члены класса копируются простым присваиванием (shallow copy), то есть если у нас есть член класса который является указателем то ему будет присвоен новый адрес и всё... при этом старая область памяти на которую он указывает «утекает», так как на неё уже никто не ссылается, а на область памяти на которую указывала присваиваемая переменная указывают 2 указателя

- А не конструкторы копирования ли он вызывает?

- ога, у char* :)

- Да. Для всех элементарных типов были введены «конструкторы» по умолчанию и «конструкторы копирования» (присвоение нуля и присвание элемент)

так вот конструктор копирования по умолчанию делает тупое побитное копирование и, следовательно, просто копирует адрес из одного указателя в другой

для встроенных типов нет конструкторов копии!

естественно когда он копирует экземпляр класса 1 в экземпляр класса 2 то вызывается конструктор копии экземпляра класса 1 :) но то не про ссылки!

shty ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.