информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медСтрашный баг в WindowsГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Крупный взлом GoDaddy 
 Просроченный сертификат ломает... 
 Phrack #70/0x46 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Звездочку пропустил 30.07.05 10:32  Число просмотров: 1175
Автор: amirul@home Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
<programming>
[C++] Инициализация переменных-членов класса нулями. 28.07.05 16:43  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Есть класс:

class a
{
// переменные класса
...
public:
a() { memset( this, 0, sizeof(a) ); }
...

// interface of the class a
...
};

Переменных много. Корректно ли использовать конструктор, как показано выше, для "обнуления" всех переменных?

Спасибо.
[C++] Про наследование забыли... 01.08.05 10:55  
Автор: Kuzmich Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
struct ___a {
int member1;
double member2;
...
};


class a: public ___a {
a() {
memset(&((___a)*this),0,sizeof(___a));
}
....
};
например вот так: 30.07.05 02:03  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
например вот так:
class A
{
    int m_i;
    float m_f;
    struct 
    {
        char*  sz;
        int i;
        float f;
    }   m_s;
};
int _tmain(int argc, _TCHAR* argv[])
{
    A *pa;
    void* p = malloc(sizeof(A));
    memset(p, 0, sizeof(A));

    pa = new (p) A();
}

---

> Есть класс:
>
> class a
> {
> // переменные класса
> ...
> public:
> a() { memset( this, 0, sizeof(a) ); }
> ...
>
> // interface of the class a
> ...
> };
>
> Переменных много. Корректно ли использовать конструктор,
> как показано выше, для "обнуления" всех переменных?
>
> Спасибо
Это можно и проще 30.07.05 10:28  
Автор: amirul@home Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
void operator new(size_t count) {return calloc(1, count);}

Но динамическая память это одно, но класс должен работать при любом способе распределения и сам инициализировать свои инварианты.
Звездочку пропустил 30.07.05 10:32  
Автор: amirul@home Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
[C++] Да, кстати 29.07.05 15:03  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
Переменные-члены инициализируются В ЛЮБОМ случае. Просто если, ты не напишешь явной инициализиции, то будут вызваны конструкторы по умолчанию. Для целочисленных типов это насколько я помню инициализация нулем.
Неа нету такой инициализации. По кр мере в стандарте и... 29.07.05 15:48  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Неа нету такой инициализации. По кр мере в стандарте и многих компиляторах.
Проверил - точно нету. Ну что ж, я заблуждался 29.07.05 23:55  
Автор: amirul@home Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
Всегда откладывал "на потом" вопрос.... Если класс A... 29.07.05 15:34  
Автор: void <Grebnev Valery> Статус: Elderman
Отредактировано 29.07.05 16:43  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
>>Для целочисленных типов это насколько я помню инициализация нулем.

Всегда откладывал "на потом" вопрос.... Если класс A содержит переменную-член типа структура struct Point3D { double x,y,z; }, то инициализация ( A* pA = new A(); ) не даёт нулевых координат x,y,z. Иногда - да, иногда - нет.

Ред. Я там звёздочку * забыл поставить ;)
нет !! это уж слишком... не ленись и обнуляй всё ручками. =) 28.07.05 17:14  
Автор: noonv <Vladimir> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
ужоснах 28.07.05 17:02  
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
до чего дошла лень Ж)
В заголовке реализации конструктора обнулять и по очереди. В крайнем случае собрать все переменные которые надо "обнулять" в структуру и обнулять в конструкторе ее. А то ну если ты потом добавишь в класс что нить что нельзя обнулять. Да хотябы виртуальную функцию...
[C++] Ок. Только маленькое замечание 28.07.05 20:23  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> до чего дошла лень Ж)
> В заголовке реализации конструктора обнулять и по очереди.
> В крайнем случае собрать все переменные которые надо
> "обнулять" в структуру и обнулять в конструкторе ее. А то
> ну если ты потом добавишь в класс что нить что нельзя
> обнулять. Да хотябы виртуальную функцию...

Спасибо за комментарий.

1. Интересен сам вопрос. Вопрос и в том, что должен возвращать sizeof() для "пустого" класса или структуры, при условии, что они не содержат переменных, а только функции, илидаже_вовсе_пустой_класс например:

class a { } ;

Компилятол VC для sizeof( a ) всегда вернёт единицу. Впрочем, как вернёт единицу и для:

class b{ char ch; );

Т.е. sizeof(a) == 1 и sizeof(a) == 1 тоже.

Таким образом,если_быи оставить вопрос о виртуальных функциях (см. ниже) - всё равно не понятно что и куда копировать.

2.
>> .... Да хотябы виртуальную функцию...

Ты здесь прав. На 100%. Хочу обратить твоё внимание, что MS опять в своих статьях с этим, кажется облажалась. Они пишутошибочносовершенно обратное:

" .... Only the non-virtual data members occupy space in each instance. "
(Visual C and C++ (General) Technical Articles. C++: Under the Hood)

Хотя, конесно, английский сложный язык... Зависит от контекста. Может я и не правильно читаю.
Повторяю, ты прав с виртуальными функциями на 100%. (в случае с виртуальными функциями, в ран тайм, появится 32-битная скрытая от программера ссылка на vtbl, еслт только не ошибаюсь)

Спасибо за реакцию.
Для того, чтобы this указывал хоть на что-то. Пустые классы... 29.07.05 13:42  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Компилятол VC для sizeof( a ) всегда вернёт единицу.
> Впрочем, как вернёт единицу и для:

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

> class b{ char ch; );
>
> Т.е. sizeof(a) == 1 и sizeof(a) == 1 тоже.
>
> Таким образом,если_быи оставить вопрос о виртуальных
> функциях (см. ниже) - всё равно не понятно что и куда
> копировать.

Если ТОЧНО нет и не будет виртуальных функций (и как следствие RTTI) и виртуального наследования, то можно заполнять нулями. В пустом классе есть неименованное поле-заполнитель. Его можно обнулять без зазрения совести

> Ты здесь прав. На 100%. Хочу обратить твоё внимание, что MS
> опять в своих статьях с этим, кажется облажалась. Они пишут
>ошибочносовершенно обратное:

Никакой ошибки.

> " .... Only the non-virtual data members occupy space in
> each instance. "
> (Visual C and C++ (General) Technical Articles. C++: Under
> the Hood)

> Хотя, конесно, английский сложный язык... Зависит от
> контекста. Может я и не правильно читаю.

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

> Повторяю, ты прав с виртуальными функциями на 100%. (в
> случае с виртуальными функциями, в ран тайм, появится
> 32-битная скрытая от программера ссылка на vtbl, еслт
> только не ошибаюсь)

Не только она. Еще и таблица базовых классов vbase (используется для RTTI), если включена RTTI
[C++] Пустые классы... 29.07.05 15:48  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
>>>.... Пустые классы
> запрещены.

Кем? Это стандарт языка?

> После добавления хоть одного члена (или
> виртуальной функции) класс становится не пустым и этот
> неименованный заполнитель можно убирать.

Не совсем точно. Не обязательно виртуальной. Класс уже не пуст, если присутствует любая функция.
Кстати класс может быть не пустым даже в том случае, если он не содержит никаких членов (переменных или функций), а содержит только модификаторы доступа к членам базового класса.


> Если ТОЧНО нет и не будет виртуальных функций (и как
> следствие RTTI) и виртуального наследования, то можно
> заполнять нулями. В пустом классе есть неименованное
> поле-заполнитель. Его можно обнулять без зазрения совести

Ну это понятно ;)

>>> Никакой ошибки.

>
> > " .... Only the non-virtual
> data members occupy space in
> > each instance. "
> > (Visual C and C++ (General) Technical Articles. C++:
> Under
> > the Hood)

Как раз здесь ошибка. Поскольку фунция - тоже мембер.

> Я так понимаю, виртуальные члены-данные это члены классов,
> отнаследованные виртуально. Члены-данные виртуального
> базового класса входят в любой класс только один раз,
> независимо от того, сколько раз этот базовый класс был
> отнаследован. Так что все правильно

Поясни, что ты имеешь ввиду. Виртуальное наследованиефункций- это виртуальное наследование. Не виртуальное - наследование не виртуальных функций. О каких виртуальныхчленах-данныхты говоришь?

> Не только она. Еще и таблица базовых классов vbase
> (используется для RTTI), если включена RTTI

Верное и полезное уточнение.

Спасибо.
Признаться, не знаю. Скорее всего да. Потому, что C-шный... 30.07.05 00:14  
Автор: amirul@home Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
> >>>.... Пустые классы
> > запрещены.
>
> Кем? Это стандарт языка?

Признаться, не знаю. Скорее всего да. Потому, что C-шный компилятор замечательно грызет пустые структуры и выдает sizeof == 0.

> Не совсем точно. Не обязательно виртуальной. Класс уже не
> пуст, если присутствует любая функция.

Я неточно выразился. Вообще то я имел в виду память под объектом класса. Обычная функция член не занимает памяти в объектах класса.

> Кстати класс может быть не пустым даже в том случае, если
> он не содержит никаких членов (переменных или функций), а
> содержит только модификаторы доступа к членам базового
> класса.

См. замечание выше

> > > " .... Only the non-virtual
> > data members occupy space in
> > > each instance. "
> > > (Visual C and C++ (General) Technical Articles.
> C++:
> > Under
> > > the Hood)
>
> Как раз здесь ошибка. Поскольку фунция - тоже мембер.

Но не data member.

> > Я так понимаю, виртуальные члены-данные это члены
> классов,
> > отнаследованные виртуально. Члены-данные виртуального

Тут очевидная ачипятка. Надо читать "члены классов, отнаследованнЫХ виртуально". Деепричастие относится к слову "классов", а не "члены". Далее по тексте понятно, что я имел в виду.

> Поясни, что ты имеешь ввиду. Виртуальное наследование
>функций- это виртуальное наследование. Не виртуальное -
> наследование не виртуальных функций. О каких виртуальных
>членах-данныхты говоришь?

Нет виртуальные функции и виртуальное наследование совершенно разные вещи.

class Base {
public:
	int member;
};

class Derived1: virtual public Base {
};

class Derived2: virtual public Base {
};

class Test: public Derived1, public Derived2 {
public:
	void test() {
		if (&Derived1::member != &Derived2::member)
			throw -1;
	}
};

int
main() {
	Test t;
	try {
		t.test();
	} catch (int i) {
		return i;
	}

	return 0;
};

---

Программа вернет 0

Я не знаю, что микрософтовцы имели в виду под виртуальными членами-данными, но члены-данные виртуального базового класса - единственное разумное объяснение

> > Не только она. Еще и таблица базовых классов vbase
> > (используется для RTTI), если включена RTTI

> Верное и полезное уточнение.
Сам впервые ее увидел при отладке под WinDbg MFC-шного кода.
[C++] на счет виртуальных функций 29.07.05 12:22  
Автор: PS <PS> Статус: Elderman
Отредактировано 29.07.05 12:24  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
#include<stdio.h>
#include<memory.h>

class A
{
public:
	int R;
public:
	A(){ R=6;printf("%ld\n", sizeof(A)); memset(this, 0, sizeof(A)); }
	int Get(){ return R; }
	virtual int Set(int){ return R; }
};

void main()
{
	printf("%ld\n", sizeof(A));
	A a;
	printf( "%ld\n", a.Set(4) );
}

---

Переменая R обнуляется, как ей и положенно. Тогда как с функцией ничего страшного не происходит. Никакого access vialation нет.
[C++] Вообще то vtable и vbase указатели устанавливаются *после* выполнения конструктора 29.07.05 13:35  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Переменая R обнуляется, как ей и положенно. Тогда как с
> функцией ничего страшного не происходит. Никакого access
> vialation нет.

Именно поэтому и работает.

Причем после выполнения КАЖДОГО конструктора базового класса. То есть

class Base {
public:
Base();
virtual ~Base();

virtual void f();
};

class Derived: public Base {
public:
Derived();
virtual ~Derived();

virtual void f();
};

class DoubleDerived: public Derived {
public:
DoubleDerived();
~DoubleDerived();

virtual void f();
};

В конструкторе Base-а виртуальные функции недоступны вообще, в конструкторе Derived-а доступны только функции Base-а, так как this по сути является указателем на Base, а Derived только конструируется, ну а в DoubleDerived доступны виртуальные функции Derived-а по той же причине. Причем, когда я говорю о доступности, следует понимать, что вызов f() в конструкторе Base скорее всего не скомпилируется (компилятор отлично все видит), а если его все таки заставить (поиграться с указателями), то это приведет к краху, вызов f() в конструкторе Derived вызовет на самом деле Base::f() (хотя this вроде как имеет тип Derived *), ну и так далее.
Замечание... Если б это было стандартом, то гипотетически... 29.07.05 16:11  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Замечание... Если б это было стандартом, то гипотетически ничего страшного не было б, на мой взгляд, в использовании memset( this, ....
Но, увы...
Особенности реализации никогда не вводятся в стандарт 29.07.05 23:47  
Автор: amirul@home Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
Стандарт может наложить кучу условий, для выполнения которых подходит единственная реализация на данной конкретной платформе, но если язык хочет оставаться платформно независимым, то никаких сведений о реализации не может быть в стандарте этого языка
ну вот и я о том, же 29.07.05 14:16  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Если особо не извращаться, то ничего страшного в обнулении переменных memset-ом нет.
1  |  2 >>  »  






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2021 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach