powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / инициализация структуры
25 сообщений из 61, страница 2 из 3
инициализация структуры
    #34992593
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TubrikКороче) достал из завалов учебник, порывшись, все-таки оформил для себя понимание структуры исходя из след. двух принципов:

1. Структура является объединением простых переменных.
2. Класс является объединением данных и функция для работы над этими данными (ну и не только).

Сделал для себя правило:
1. Хранить в структуре только простые типы данных.
2. Даже не думать манипулировать любыми данными через структуру (т.е. никаких методов внутри).
3. п.1. позволяет беспечно использовать memset() и ему подобные.
4. Если есть необходимость постоянно однообразно изменять данные в структуре, сделать для этого специальную ф-ию.

Если кратко:
структура - это данные и ничего больше!

аж легче стало =)

А к чему это правило? Структуры могут содержать и пользовательские типы также. По мне, лучше разделять поведенческие сущности - их следует оформлять как класс и инкапсулировать состояние, и вспомогательные сущности - их следует оформлять как структуры и предоставлять открытый доступ к членам данным.
...
Рейтинг: 0 / 0
инициализация структуры
    #34992600
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков

А к чему это правило? Структуры могут содержать и пользовательские типы также. По мне, лучше разделять поведенческие сущности - их следует оформлять как класс и инкапсулировать состояние, и вспомогательные сущности - их следует оформлять как структуры и предоставлять открытый доступ к членам данным.

я же уже исправил этот момент
...
Рейтинг: 0 / 0
инициализация структуры
    #34992607
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik Анатолий Широков
Вы выборочно читаете ленту? Я уже ответил на этот вопрос выше:
Код: plaintext
stTest s = {};


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

Для "зануления" подобного рода структур используется тот факт, что для глобальных объектов (и статических в том числе) всегда выполняется так называемая "zero-initialization". Используя это обнулять структуры можно в любом месте с помощью "зануленного" объекта и, как видите, никаких трюков с memset и никаких требований POD:


Код: plaintext
1.
2.
3.
ssTest globalEmptyObject; // компилятор сам выполнит zero-initialization

// в любом месте программы
ssTest s(globalEmptyObject);
...
Рейтинг: 0 / 0
инициализация структуры
    #34992613
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков Tubrik Анатолий Широков
Вы выборочно читаете ленту? Я уже ответил на этот вопрос выше:
Код: plaintext
stTest s = {};


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

Для "зануления" подобного рода структур используется тот факт, что для глобальных объектов (и статических в том числе) всегда выполняется так называемая "zero-initialization". Используя это обнулять структуры можно в любом месте с помощью "зануленного" объекта и, как видите, никаких трюков с memset и никаких требований POD:


Код: plaintext
1.
2.
3.
ssTest globalEmptyObject; // компилятор сам выполнит zero-initialization

// в любом месте программы
ssTest s(globalEmptyObject);



Это даже слишком сложно :) Чтобы обнулить подобного рода структуру достаточно, все лишь:), следующего:

Код: plaintext
1.
ssTest s; // мусор из стека
s = ssTest(); // обнуление
...
Рейтинг: 0 / 0
инициализация структуры
    #34992617
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
+
настолько просто, что я бы не догадался сам =)
...
Рейтинг: 0 / 0
инициализация структуры
    #34992628
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik+
настолько просто, что я бы не догадался сам =)

Но хочу предупредить, не все компиляторы корректно генерируют код для вызова
s = ssTest();

А zero-initialization выполняется всеми мне известными компиляторами. Поэтому иногда обнуление с помощью глобального объекта является единственно возможным безтрюковым вариантом.
...
Рейтинг: 0 / 0
инициализация структуры
    #34992636
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik wrote:

> Для структуры не создается конструктор по-умолчанию, как и конструктор
> копирования.
Щас тебе. Создается, и он требует себе struct& в качестве аргумента.
То же самое с конструктором копирования.

> просто скажите кто как обнуляет структуру? я всегда юзал memset(), и,
> мне кажется ничего плохого в этом нет, если уверен, что она
> (структура) всегда будет содержать в себе только встроенные типы
> данных
А зачем тебе обнулять структуру? сделай к ней конструктор.

> 1. Структура является объединением простых переменных.
А что мне мешает включить в структуру класс?

>2. Класс является объединением данных и функция для работы над этими
>данными (ну и не только).
Код: plaintext
1.
2.
3.
4.
5.
6.
#include <stdio.h>
class A{
        void foo(){
                printf("hw!\n");
        }
};
Ну и где данные?

> Сделал для себя правило:
> 1. Хранить в структуре только простые типы данных.
Смысл?

>2. Даже не думать манипулировать любыми данными через структуру (т.е.
>>никаких методов внутри).
Почему?

> 3. п.1. позволяет беспечно использовать memset() и ему подобные.
Никто тебе не запрещает использовать memset для класса, как я понимаю :)
4. Если есть необходимость постоянно однообразно изменять данные в
структуре, сделать для этого специальную ф-ию.

> Если кратко:
> структура - это данные и ничего больше!
Ок, а указатель на метод - это данные или функция?
--
We are all going to hell and I'm driving the bus
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
инициализация структуры
    #34992648
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ErV
Tubrik wrote:

> Для структуры не создается конструктор по-умолчанию, как и конструктор
> копирования.
Щас тебе. Создается, и он требует себе struct& в качестве аргумента.
То же самое с конструктором копирования.

Для структур являющихся агрегатами этот конструктор очень хитрый. Вот так, например, не будет осуществляться "зануление":

Код: plaintext
ssTest s; // в полях будет мусор

А при явном вызове конструктора, будет :
ssTest s = ssTest(); // все члены структуры будут "занулены"

Заметьте, насколько это поведение отличается от поведения рукописного конструктора по умолчанию.

ErV
> просто скажите кто как обнуляет структуру? я всегда юзал memset(), и,
> мне кажется ничего плохого в этом нет, если уверен, что она
> (структура) всегда будет содержать в себе только встроенные типы
> данных
А зачем тебе обнулять структуру? сделай к ней конструктор.

А вот ерунды советовать не надо. Представьте себе структуру из 40 членов данных - это что же, я в конструкторе должен их всех перечислить, чтобы провести корректное обнуление (я не рассматриваю возможные решения для POD типов, где можно использовать memset). Здесь, как нельзя кстати, не только нужно, но и необходимо использовать сгенерированный компилятором конструктор.
...
Рейтинг: 0 / 0
инициализация структуры
    #34992653
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ErV


а). а что мешает, если уж так нужно манипулировать данными, назвать ее class вместо struct, добавив слово public, чтобы позволить себе и др. в любой момент понять, что в вашем коде struct подразумевает одно, class - другое?

б). потому, что мне так будет удобнее работать со своим кодом (если это не так, то время покажет).

г). указатель на метод буду считать данными, ибо _моя_ структура никогда не вызовет этот метод, ибо нечем вызвать

д). printf() - буду считать методом манипулирующим над данными, ибо он выводит данные в консоль, чем не манипуляция? разве что-то мешает писать:

Код: plaintext
1.
2.
int a;
printf("%d", ++a);

е). и так понятно, что все эти разделения лишь дело личного предпочтения и уважения к др. людям, которым может понадобиться использовать этот код. Способ абстрагирования и т.п... тут уже попрет философия, поэтому лучше не надо. На уровне машинного кода вообще нет принципиальной разницы между кодом и данными, и что? Все эти правила лишь для собственного удобства.
...
Рейтинг: 0 / 0
инициализация структуры
    #34992663
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков
Для структур являющихся агрегатами этот конструктор очень хитрый. Вот так, например, не будет осуществляться "зануление":

Код: plaintext
ssTest s; // в полях будет мусор

А при явном вызове конструктора, будет :
ssTest s = ssTest(); // все члены структуры будут "занулены"

Заметьте, насколько это поведение отличается от поведения рукописного конструктора по умолчанию.


у меня в обоих случаях получается мусор, поэтому пока такое решение:

делаю статическую ф-ию или обычную, с вложенной статической переменной, типа:

Код: plaintext
1.
2.
3.
4.
5.
void MyObj::ZeroStruct(stMyStruct& st)
{
	static stMyStruct zero_obj = {};
	st = zero_obj;
}

думаю будет работать
...
Рейтинг: 0 / 0
инициализация структуры
    #34992667
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik ErV


а). а что мешает, если уж так нужно манипулировать данными, назвать ее class вместо struct, добавив слово public, чтобы позволить себе и др. в любой момент понять, что в вашем коде struct подразумевает одно, class - другое?

б). потому, что мне так будет удобнее работать со своим кодом (если это не так, то время покажет).

г). указатель на метод буду считать данными, ибо _моя_ структура никогда не вызовет этот метод, ибо нечем вызвать

д). printf() - буду считать методом манипулирующим над данными, ибо он выводит данные в консоль, чем не манипуляция? разве что-то мешает писать:

Код: plaintext
1.
2.
int a;
printf("%d", ++a);

е). и так понятно, что все эти разделения лишь дело личного предпочтения и уважения к др. людям, которым может понадобиться использовать этот код. Способ абстрагирования и т.п... тут уже попрет философия, поэтому лучше не надо. На уровне машинного кода вообще нет принципиальной разницы между кодом и данными, и что? Все эти правила лишь для собственного удобства.

В любом случае, я бы вам не советовал себя настолько ограничивать. Вот хочу, чтобы вы поразмышляли над сущность "ТОЧКА". В своем проекте я его сделал структурой агрегатом с огромным количеством методов, которые в том числе изменяют состояние самого объекта. А структуру я оставил всего лишь для того, чтобы все понимали, что это вспомогательный класс, который имеет легковестный сгенерированный конструктор и который легко можно помещать в контейнеры типа std::vector и т.п.
...
Рейтинг: 0 / 0
инициализация структуры
    #34992669
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik Анатолий Широков
Для структур являющихся агрегатами этот конструктор очень хитрый. Вот так, например, не будет осуществляться "зануление":

Код: plaintext
ssTest s; // в полях будет мусор

А при явном вызове конструктора, будет :
ssTest s = ssTest(); // все члены структуры будут "занулены"

Заметьте, насколько это поведение отличается от поведения рукописного конструктора по умолчанию.


у меня в обоих случаях получается мусор, поэтому пока такое решение:


Видимо, вы пользуетесь компилятором от MS.

Tubrik
делаю статическую ф-ию или обычную, с вложенной статической переменной, типа:

Код: plaintext
1.
2.
3.
4.
5.
void MyObj::ZeroStruct(stMyStruct& st)
{
	static stMyStruct zero_obj = {};
	st = zero_obj;
}

думаю будет работать

Можно даже сократить ;)
вместо
Код: plaintext
	static stMyStruct zero_obj = {};
оставить
Код: plaintext
	static stMyStruct zero_obj;
и тоже все будет работать, поскольку в данном случае компилятор сам выполнить "zero-initializatio".
Удачи!
...
Рейтинг: 0 / 0
инициализация структуры
    #34992676
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков

я уж лучше подстрахуюсь = {}, всего 3 лишних символа - это не много :)

по поводу точки, тут же опять, смотря с какой позиции размышлять, сделали бы вы ее классом, она бы не перестала быть точкой, кроме того было бы сразу видно, что все же? манипуляции над данными будут иметь место, а о легковесности знать, возможно, и не так приоритетно, как о том, что к ней не стоит применять memset().
...
Рейтинг: 0 / 0
инициализация структуры
    #34992681
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
подсократил еще немного :)
Код: plaintext
1.
2.
3.
4.
5.
stStruct ZeroStruct()
{
	static stStruct zero_obj;
	return zero_obj;
}
...
Рейтинг: 0 / 0
инициализация структуры
    #34992686
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
надеюсь окончательный вариант:

Код: plaintext
1.
2.
3.
4.
5.
const stStruct& ZeroStruct()
{
	static stStruct zero_obj;
	return zero_obj;
}

чтобы никто не сделал
ZeroStruct() = st;
...
Рейтинг: 0 / 0
инициализация структуры
    #34992801
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrikнадеюсь окончательный вариант:

Код: plaintext
1.
2.
3.
4.
5.
const stStruct& ZeroStruct()
{
	static stStruct zero_obj;
	return zero_obj;
}

чтобы никто не сделал
ZeroStruct() = st;

Никто и не сделает, поскольку результат выполнения функции stStruct ZeroStruct() является r-value, к которому неприменим operator=();

И еще на мой взгляд, помещение функции "обнуления" в интерфейс структуры отражает общность и сокращает имя:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
// header.h

struct stStruct {
     ....
     static stStruct empty() {
         static stStruct temp;
         return temp;
     }
};

Сравните stStruct::empty() с ZeroStruct().
...
Рейтинг: 0 / 0
инициализация структуры
    #34992809
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik Анатолий Широков

я уж лучше подстрахуюсь = {}, всего 3 лишних символа - это не много :)

по поводу точки, тут же опять, смотря с какой позиции размышлять, сделали бы вы ее классом, она бы не перестала быть точкой, кроме того было бы сразу видно, что все же? манипуляции над данными будут иметь место, а о легковесности знать, возможно, и не так приоритетно, как о том, что к ней не стоит применять memset().

О легковесности знать важнее, уверяю вас. Ну да ладно. Не буду мешать зарабатывать вам свои собственные шишки ;)
...
Рейтинг: 0 / 0
инициализация структуры
    #34992833
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков wrote:

> А вот ерунды советовать не надо.
Ерунда или нет - зависит от ситуации. Ситуации не имеем.

Tubrik wrote:
> а). а что мешает, если уж так нужно манипулировать данными, назвать ее
> class вместо struct, добавив слово public, чтобы позволить себе и др.
> в любой момент понять, что в вашем коде struct подразумевает одно,
> class - другое?
структура и класс - это одно и то же. Кроме того, они оба ещё являются
пространствами имен. Соответственно, слово struct или класс сакрального
смысла себе не несет, различие только в дефолтном разрешении на доступ

> б). потому, что мне так будет удобнее работать со своим кодом (если
> это не так, то время покажет).
Не обижайся, но для меня это выглядит, как пустая трата времени.
У тебя есть гибкий и подвижный язык - C++. Теперь ты хочешь сделать для
себя одно корявое и неудобное правило, чтобы его испортить.

Представь, что ты, говоря по русски, решил себе добавить ещё одно
правило, например не употреблять слова, начинающиеся с буквы "в", после
слов, начинающихся с буквы "а". Смысл в этом есть? Может, и есть. Но,
скорее всего, нету.

Вот так же и с разделением класс/структура. Какая разница, в каком
случае что использовать? Используй то, что удобнее в данном случае, не
надо из пальца правила высасывать. Просто работай так, чтобы тебе было
удобно на этом языке писАть, и желательно, на нем же и думать. Вот и
все.

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

Это из разряда с негласным запретом на использование goto. Иногда он не
нужен, но есть ситуации, когда без трудно не обойтись, и с
использованием goto код получается более кратким и понятным.

То же самое с рекомендациями не использовать много макросов. Да, есть
ситуация, когда макросы запутывают программы. Но бывает ситуация, когд
надо, например, сделать функцию, возвращающую числовое имя ошибки для
её кода. Тогда быстрее воспользоваться макросом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
const char* glErrorString(GLuint error){
        switch (error){
#define branch(p) case(p): return #p; 
        branch(GL_NO_ERROR)
        branch(GL_INVALID_ENUM)
        branch(GL_INVALID_VALUE)
        branch(GL_INVALID_OPERATION)
        branch(GL_STACK_OVERFLOW)
        branch(GL_STACK_UNDERFLOW)
        branch(GL_OUT_OF_MEMORY)
        branch(GL_TABLE_TOO_LARGE)
                default:
                        return "Unknown error\n";
#undef  branch
        };
}


И так с любыми гласными/негласными запретами. Просто пиши так, как тебе
удобно, и не загоняйся с выдумыванием правил типа этого. struct или
class - это не принципиально.
--
We are all going to hell and I'm driving the bus
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
инициализация структуры
    #34992860
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий ШироковИ еще на мой взгляд, помещение функции "обнуления" в интерфейс структуры отражает общность и сокращает имя:

насчет общности готов согласиться и объявить ф-ию внутри, но только потому, что она статическая :)

Анатолий ШироковНикто и не сделает, поскольку результат выполнения функции stStruct ZeroStruct() является r-value, к которому неприменим operator=();

очень даже сделает, вы пропустили знак stStruct & ZeroStruct()
...
Рейтинг: 0 / 0
инициализация структуры
    #34992869
Leshij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On Thu, 06 Dec 2007 22:51:12 +0300, ErV <nospam@sql.ru>; wrote:

> И так с любыми гласными/негласными запретами. Просто пиши так, как тебе
> удобно, и не загоняйся с выдумыванием правил типа этого. struct или
> class - это не принципиально.

+1
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
инициализация структуры
    #34992885
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ErV


Еще раз повторюсь, это дело личного предпочтения, просто я решил считать, что если язык не запрещает, то это еще не значит, что это надо использовать. Со временем, возможно, я изменю точку зрения, если найду это в чем-то неэффективным.

Про подстановку букв пример не слишком удачный и очень отстраненный от темы. Синтаксис русского языка не запрещает ругаться матом, но не все делают это везде, где вздумается, т.к. есть места, где это, по крайней мере, не разумно делать. Чем не ограничение?
Синтаксис С++ не обязывает писать имена переменных класса с "m_", имена классов с большой буквы, и т.д. и т.п., но некоторые так делают, и я в их числе.
Можно не использовать классы, и даже ф-ии, это язык тоже не запрещает. Ну а что тут такого? Может так кому удобно!

Я не считаю, что "порчу" С++ или как-то ограничиваю его подвижность, а просто выбираю более удобное слово для использования, чтобы более точно (для себя) отразить замысел какого-то момента. К примеру, если более удобно использовать typename, чем class в шаблонах, то я не вижу ничего отрицательного в этом, никакого ущемления языка.

Какой-то (не помню) автор книги по правилам "хорошего" тона в С++ сказал, что этот язык слишком уж гибкий, чтобы не вводить подобные ограничения. По-твоему все эти книги с рекомендациями можно смело в топку?
...
Рейтинг: 0 / 0
инициализация структуры
    #34993161
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik Akh
Не то что не совсем справедливо, а безобразие.


а как тогда быстро и кратко обнулить структуру типа :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
struct stTest
{
	int a;
	double b;
	/*... 
	огромный список
	...*/
};

?

Да за ради бога, только если там примитивные типы.
...
Рейтинг: 0 / 0
инициализация структуры
    #34993169
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrikпросто скажите кто как обнуляет структуру? я всегда юзал memset(), и, мне кажется ничего плохого в этом нет, если уверен, что она (структура) всегда будет содержать в себе только встроенные типы данных

аналогично. Лично мне это больше по душе, чем {0}. У меня психологически это ассоциируется только с первым элементом. Мало ли чего там в следующем стандарте наворотят. :)
...
Рейтинг: 0 / 0
инициализация структуры
    #34993182
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrikи сразу же нарушил свое же правило, добавив в структуру поля std::string =)

в связи с чем внес поправку:

Структура - это объединение любых типов данных, без каких-либо возможных манипуляций над данными, как внутренними, так и внешними. (а чем там будут эти данные заниматься внутри структуры - это уже не ее проблемы)
Для повторяющихся обнулений и др. переинициализаций использовать внешние ф-ии.

Вроде все стыкуется, жаль только memset уже не применишь.

А чего констктор не применить для обнулений?

Поехала теория? ;)
...
Рейтинг: 0 / 0
инициализация структуры
    #34993184
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blindedИ снова мир поделился на остро- и тупоконечников. Аминь

Сейчас опять ретроградами будешь обзываться? ;)
...
Рейтинг: 0 / 0
25 сообщений из 61, страница 2 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / инициализация структуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]