информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
За кого нас держат?Атака на InternetПортрет посетителя
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Замечание... Если б это было стандартом, то гипотетически... 29.07.05 16:11  Число просмотров: 1275
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Замечание... Если б это было стандартом, то гипотетически ничего страшного не было б, на мой взгляд, в использовании memset( this, ....
Но, увы...
<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-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach