Nested class
26 отговора
1043 прегледа
Nested class
Искам някой да ми обясни как точно функцията GetParent получава
указател към обекта на външния клас.
Съжалявам че се размазва кода но какво да се прави няма "insert CODE" в форума.
/////////////////////////////////////////////////////////////////////
#include <iostream>
class PClass{
public:
PClass(int nData){
m_nData = nData;
}
~PClass(){}
void Print(){
m_localClass.Print();
}
private:
class LClass{
public:
LClass(){}
~LClass(){}
void Print(){
std::cout << GetParent()->m_nData << std::endl;
}
private:
PClass* GetParent(){
return (PClass*)((char*)this - (unsigned int)&(((PClass*)0)->m_localClass));
}
} m_localClass;
int m_nData;
};
//////////////////////////////////////////////////////////////////////////////////////////////////
int main(){
PClass obj(8);
obj.Print();
return 0;
}
указател към обекта на външния клас.
Съжалявам че се размазва кода но какво да се прави няма "insert CODE" в форума.
/////////////////////////////////////////////////////////////////////
#include <iostream>
class PClass{
public:
PClass(int nData){
m_nData = nData;
}
~PClass(){}
void Print(){
m_localClass.Print();
}
private:
class LClass{
public:
LClass(){}
~LClass(){}
void Print(){
std::cout << GetParent()->m_nData << std::endl;
}
private:
PClass* GetParent(){
return (PClass*)((char*)this - (unsigned int)&(((PClass*)0)->m_localClass));
}
} m_localClass;
int m_nData;
};
//////////////////////////////////////////////////////////////////////////////////////////////////
int main(){
PClass obj(8);
obj.Print();
return 0;
}
Re: Nested class
Ми това: (unsigned int)&(((PClass*)0)->m_localClass)
ти дава отместването на точно този локален клас от началото на парент класа, вадиш го от твойто начало и така...
Ама това е яко грозен хак и нямам идея дали е стандартно....
Лека нощ
ти дава отместването на точно този локален клас от началото на парент класа, вадиш го от твойто начало и така...
Ама това е яко грозен хак и нямам идея дали е стандартно....
Лека нощ
Re: Nested class
Да бе то ясно че е отместването :)
То реално е като действието на offsetof.
Но, това ((PClass*)0)->m_localClass
как така става ?
То реално е като действието на offsetof.
Но, това ((PClass*)0)->m_localClass
как така става ?
Re: Nested class
Интересен е въпросът. Накратко:
1. С++ работи с паметта на достатъчно ниско ниво, че да работи с нея с директна адресация.
2. Паметта е представена като flat.
3. Всеки обект заема определена памет - от адрес X, до адрес Х + големината_на_обекта. За леснота, ще наречем заеманата от обекта памет "адресно пространство на обекта"
4. Атрибутът m_localClass е обект, и неговото адресно пространство се намира в адресното пространство на обекта от клас PClass.
Сега следва интересната част.
5. За компилатора адресното пространство на обекта m_localClass представлява отместване от адресното пространство на обекта PClass.(прочети внимателно 3. и 4.).
6. Операторът -> добавя отместването на члена (атрибут или функция) намиращ се непосредствено след него, към адреса на обекта указан непосредствено преди оператора, СПРЯМО същия този обект.
7. Следователно, ако се подаде обект намиращ се на адрес нула преди оператора ((unsigned int)&(((PClass*)0)), то сборът ще бъде равен на отместването.
8. Ако от адреса на вътрешния обект извадим отместването...
Аз го наричам указателна алгебра.
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
1. С++ работи с паметта на достатъчно ниско ниво, че да работи с нея с директна адресация.
2. Паметта е представена като flat.
3. Всеки обект заема определена памет - от адрес X, до адрес Х + големината_на_обекта. За леснота, ще наречем заеманата от обекта памет "адресно пространство на обекта"
4. Атрибутът m_localClass е обект, и неговото адресно пространство се намира в адресното пространство на обекта от клас PClass.
Сега следва интересната част.
5. За компилатора адресното пространство на обекта m_localClass представлява отместване от адресното пространство на обекта PClass.(прочети внимателно 3. и 4.).
6. Операторът -> добавя отместването на члена (атрибут или функция) намиращ се непосредствено след него, към адреса на обекта указан непосредствено преди оператора, СПРЯМО същия този обект.
7. Следователно, ако се подаде обект намиращ се на адрес нула преди оператора ((unsigned int)&(((PClass*)0)), то сборът ще бъде равен на отместването.
8. Ако от адреса на вътрешния обект извадим отместването...
Аз го наричам указателна алгебра.
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Re: Nested class
Добре бе, като е буламач
как по друг начин можеш да се достъпваш данните на външния клас от вътрешния ?
За справка виж METHOD_PROLOGUE
как по друг начин можеш да се достъпваш данните на външния клас от вътрешния ?
За справка виж METHOD_PROLOGUE
Re: Nested class
Не гърми, щото не се прави опит да се ДОСТЪПИ паметта, а само си играеш с адресите. Ако гръмне с access violation, то е все едно да осъдиш адвокат, че чете за престъпленията на подсъдимия...
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Re: Nested class
class Vanshen {
class Vatreshen
{
private:
Vanshen *parent;
public:
Vatreshen(Vanshen *p) { parent = p; }
};
};
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
class Vatreshen
{
private:
Vanshen *parent;
public:
Vatreshen(Vanshen *p) { parent = p; }
};
};
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Re: Nested class
Естествено че и така става, но не мислиш ли предния вариант е по-добър ?
Re: Nested class
Ми ако имаш повече от един мембер от тоя тип вече няма да стане ...т.е. тая 'икономия' дето се прави няма да има полза от нея.
И все пак някой наясно ли е това дали е легално Цпп? За POD типове май трябва да е ОК ама ако не са...?
Лека нощ
И все пак някой наясно ли е това дали е легално Цпп? За POD типове май трябва да е ОК ама ако не са...?
Лека нощ
Редактирано от Maтa Kocмaтa на
Re: Nested class
Така изгаряш със паметта заемана от един указател.... (Което всъшност не е наложително...)
Все пак е препоръчително да се ползва твоя вариант - по-чисто е така да се каже...
Все пак е препоръчително да се ползва твоя вариант - по-чисто е така да се каже...
Re: Nested class
Естествено че е легално. Нещо като с goto е: върши работа но не бива да се прекалява с него. Виждал съм такива трикове в драйвери, но и аз не съм фен.
Иначе, (щом ползваме С++) по-добре следното:
struct master;
struct child
{
master *parent() { return static_cast<master *>(this); }
...
}
struct master: child
{
...
};
Иначе, (щом ползваме С++) по-добре следното:
struct master;
struct child
{
master *parent() { return static_cast<master *>(this); }
...
}
struct master: child
{
...
};
Re: Nested class
>> Естествено че е легално
сори, само за POD-ове се отнася. Ама то другото за мен не е С++
сори, само за POD-ове се отнася. Ама то другото за мен не е С++
Re: Nested class
Всичко зависи от това какво точно искаш да направиш.
Въпроса беше за вложени класове.
А иначе ако е удобно аз предпочитам наследяването, но не така както си го показал. Защото ако наследя child от друг клас тогава master *parent() няма смисъл. По добрия вариант при наследяване е :
struct child
{
virtual void AccessMaster() = 0;
};
struct master: child
{
void AccessMaster(){// TODO}
};
Ако обаче имам повече от един child класа тогава наследяването няма да върши работа (в общия случай) и ще трябва да използвам вложени класове.
Няма да върши работа щото ще се наложи множествено наследяване и има вероятност да съвпаднат имена на функции в отделните child класове.
Въпроса беше за вложени класове.
А иначе ако е удобно аз предпочитам наследяването, но не така както си го показал. Защото ако наследя child от друг клас тогава master *parent() няма смисъл. По добрия вариант при наследяване е :
struct child
{
virtual void AccessMaster() = 0;
};
struct master: child
{
void AccessMaster(){// TODO}
};
Ако обаче имам повече от един child класа тогава наследяването няма да върши работа (в общия случай) и ще трябва да използвам вложени класове.
Няма да върши работа щото ще се наложи множествено наследяване и има вероятност да съвпаднат имена на функции в отделните child класове.
Re: Nested class
Ааа искам да отбележа: Това е някакъв вариант, но не е моя вариант. Моят вариант е по-прост - не ползвам вложени класове. :)
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Re: Nested class
Тва програмистите сиебало мамата. В съседни теми се спори .NET vs. Java, а тука се притесняват за някви си 4 байта, баси. 

Re: Nested class
Що ми се струва че се занимаваш с ембеднати простотии и ще разбереш проблема... (а може би се бъркам...)
То иначе на паметта цените са ниски и мегабайтите са като вестници... само да има кой да ги чете(пише)...
То иначе на паметта цените са ниски и мегабайтите са като вестници... само да има кой да ги чете(пише)...
Re: Nested class
Е, когато става дума за ограничени ресурси - да. Ама за десктоп паметта е стотинки...