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 Статус: Незарегистрированный пользователь
Переменные-члены инициализируются В ЛЮБОМ случае. Просто если, ты не напишешь явной инициализиции, то будут вызваны конструкторы по умолчанию. Для целочисленных типов это насколько я помню инициализация нулем.
Неа нету такой инициализации. По кр мере в стандарте и...29.07.05 15:48 Автор: Killer{R} <Dmitry> Статус: Elderman
>>Для целочисленных типов это насколько я помню инициализация нулем.
Всегда откладывал "на потом" вопрос.... Если класс A содержит переменную-член типа структура struct Point3D { double x,y,z; }, то инициализация ( A* pA = new A(); ) не даёт нулевых координат x,y,z. Иногда - да, иногда - нет.
Ред. Я там звёздочку * забыл поставить ;)
нет !! это уж слишком... не ленись и обнуляй всё ручками. =)28.07.05 17:14 Автор: noonv <Vladimir> Статус: Member
до чего дошла лень Ж)
В заголовке реализации конструктора обнулять и по очереди. В крайнем случае собрать все переменные которые надо "обнулять" в структуру и обнулять в конструкторе ее. А то ну если ты потом добавишь в класс что нить что нельзя обнулять. Да хотябы виртуальную функцию...
[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
> После добавления хоть одного члена (или > виртуальной функции) класс становится не пустым и этот > неименованный заполнитель можно убирать.
Не совсем точно. Не обязательно виртуальной. Класс уже не пуст, если присутствует любая функция.
Кстати класс может быть не пустым даже в том случае, если он не содержит никаких членов (переменных или функций), а содержит только модификаторы доступа к членам базового класса.
> Если ТОЧНО нет и не будет виртуальных функций (и как > следствие 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
> Переменая 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
Стандарт может наложить кучу условий, для выполнения которых подходит единственная реализация на данной конкретной платформе, но если язык хочет оставаться платформно независимым, то никаких сведений о реализации не может быть в стандарте этого языка
ну вот и я о том, же29.07.05 14:16 Автор: PS <PS> Статус: Elderman