Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | |
Для того, чтобы this указывал хоть на что-то. Пустые классы... 29.07.05 13:42 Число просмотров: 1294
Автор: 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
|
<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-ом нет.
|
|
|