Nested class

26 отговора 1043 прегледа
#1

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;
}

Отговор
в отговор на FireStarter #2

Re: Nested class

Ми това: (unsigned int)&(((PClass*)0)->m_localClass)
ти дава отместването на точно този локален клас от началото на парент класа, вадиш го от твойто начало и така...

Ама това е яко грозен хак и нямам идея дали е стандартно....

Лека нощ
Отговор
в отговор на FireStarter #3

Re: Nested class

Това е убийствено просто. Уволнен ли е авторът на буламача?



Отговор
в отговор на Maтa Kocмaтa #4

Re: Nested class

Да бе то ясно че е отместването :)
То реално е като действието на offsetof.

Но, това ((PClass*)0)->m_localClass
как така става ?

Отговор
в отговор на FireStarter #5

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. Ако от адреса на вътрешния обект извадим отместването...

Аз го наричам указателна алгебра.

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор
в отговор на Pekoнcтpykтop #6

Re: Nested class

Добре бе, като е буламач
как по друг начин можеш да се достъпваш данните на външния клас от вътрешния ?

За справка виж METHOD_PROLOGUE

Отговор
в отговор на FireStarter #7

Re: Nested class

Не гърми, щото не се прави опит да се ДОСТЪПИ паметта, а само си играеш с адресите. Ако гръмне с access violation, то е все едно да осъдиш адвокат, че чете за престъпленията на подсъдимия...

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор
в отговор на Duncan Griffin #8

Mersi

Точно това ме интересуваше :)

Отговор
в отговор на FireStarter #9

Re: Nested class

class Vanshen {

class Vatreshen
{
private:
Vanshen *parent;

public:
Vatreshen(Vanshen *p) { parent = p; }

};

};

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор
в отговор на Duncan Griffin #10

Re: Nested class


Естествено че и така става, но не мислиш ли предния вариант е по-добър ?

Отговор
в отговор на FireStarter #11

Re: Nested class

Ми ако имаш повече от един мембер от тоя тип вече няма да стане ...т.е. тая 'икономия' дето се прави няма да има полза от нея.

И все пак някой наясно ли е това дали е легално Цпп? За POD типове май трябва да е ОК ама ако не са...?

Лека нощ

Редактирано от Maтa Kocмaтa на

Отговор
в отговор на Duncan Griffin #12

Re: Nested class

Така изгаряш със паметта заемана от един указател.... (Което всъшност не е наложително...)

Все пак е препоръчително да се ползва твоя вариант - по-чисто е така да се каже...

Отговор
в отговор на Maтa Kocмaтa #13

Re: Nested class

Естествено че е легално. Нещо като с goto е: върши работа но не бива да се прекалява с него. Виждал съм такива трикове в драйвери, но и аз не съм фен.

Иначе, (щом ползваме С++) по-добре следното:

struct master;
struct child
{
master *parent() { return static_cast<master *>(this); }
...
}
struct master: child
{
...
};

Отговор
в отговор на xyz #14

Re: Nested class

>> Естествено че е легално
сори, само за POD-ове се отнася. Ама то другото за мен не е С++

Отговор
в отговор на xyz #15

Re: Nested class

Всичко зависи от това какво точно искаш да направиш.
Въпроса беше за вложени класове.
А иначе ако е удобно аз предпочитам наследяването, но не така както си го показал. Защото ако наследя child от друг клас тогава master *parent() няма смисъл. По добрия вариант при наследяване е :


struct child
{
virtual void AccessMaster() = 0;
};

struct master: child
{
void AccessMaster(){// TODO}
};

Ако обаче имам повече от един child класа тогава наследяването няма да върши работа (в общия случай) и ще трябва да използвам вложени класове.
Няма да върши работа щото ще се наложи множествено наследяване и има вероятност да съвпаднат имена на функции в отделните child класове.

Отговор
в отговор на фдц #16

Re: Nested class

Ааа искам да отбележа: Това е някакъв вариант, но не е моя вариант. Моят вариант е по-прост - не ползвам вложени класове. :)

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор
в отговор на фдц #17

Re: Nested class

Тва програмистите сиебало мамата. В съседни теми се спори .NET vs. Java, а тука се притесняват за някви си 4 байта, баси.



Отговор
в отговор на Pekoнcтpykтop #18

Re: Nested class

Що ми се струва че се занимаваш с ембеднати простотии и ще разбереш проблема... (а може би се бъркам...)
То иначе на паметта цените са ниски и мегабайтите са като вестници... само да има кой да ги чете(пише)...

Отговор
в отговор на Duncan Griffin #19

Re: Nested class

Е съгласих се... Не е твоя вариант.

Отговор
в отговор на фдц #20

Re: Nested class

Е, когато става дума за ограничени ресурси - да. Ама за десктоп паметта е стотинки...



Отговор