protected в C++ (возможен ли доступ к "закрытым" членам объекта)

Модератор: Модераторы разделов

Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

protected в C++

Сообщение wzrd »

сразу предупрежу, что в C++ я можно сказать никак. вопрос может и дилетантский. что-то интересно мне стало как защищены свойства или методы класса при обявлении их как protected. как это работает? пробовал забивать объект каким нибудь значением с помощью memset' а. получилось следущее: при забивании всего объекта, исключение не срабатывает, а если чуть смещаюсь и забиваю лишь часть, то срабатывает. вот примерный код:

Код: Выделить всё

class foo {
      public:
              int a;
      protected:
              int a1;
              int a2;
}
...
foo *ptr=new foo;
memset (ptr, 1, sizeof (foo) ); // это работает нормально
memset (ptr+(2*sizeof (int)), 2, sizeof (int)); //срабатывает исключение

в синтаксисе мог и ошибиться, но думаю вопрос ясен. это я делал на borland' овском компиляторе. на gcc не пробывал.
Спасибо сказали:
d_n_k
Сообщения: 636
ОС: Gentoo GNU/Linux

Re: protected в C++

Сообщение d_n_k »

от прямой записи в память не защищено ни что.

если ты будешь самостоятельно ковыряться в служебных таблицах классов и писать куда следует то все будет работать.
таким способом можно записать не только в данные класса но и менять таблицу методов (если она имеется)


исключения будут только при попытке в не доступную для записи память.

таким образом можно писать в свое адресное пространство и в чужое если получишь права на запись
все сказанное есть имхо...
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

это понятно. но у меня возникает исключение... поэтому и спрашиваю. кстати возможно на прикладном уровне сделать память не доступной на запись. если да, то как?
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: protected в C++

Сообщение RasenHerz »

прежде чем писать подобный посты внимательно почитай книги по ООП(могу посоветовать автора - В.Штерн). Protected - всего лишь механизм, ограничивающий доступ к сервисам базового класса, производным от него классам + клиенту.
память можно защищать, не помню точно как, последний раз я такое выделывал когда писал модули ядра(там я все проворачивал mmap()) =))) так что гугл в помощь.
от прямой записи в память не защищено ни что.

сомнительное утверждение, абсолютно верное лишь в системах реального времени. где вся память доступному любому желающему. в остальных случаях все зависит от ядра.

P.S. если бы Бьерн прочел этот пост его бы инфаркт хватил)))
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

В приведеном примере я бы не был столь уверен, что a,a1,a2 будут расположены именно в такой последовательности. Более того, их расположение может меняться в зависимости от настроек компилятора. Вообще в данном примере имеется стилевая ошибка. Использовать memset, как указано в примере, в программе на c++ более чем не рекомендуется. Нечто подобное я проворачивал на C со структурами, но даже там, чтобы быть увереным в расположении элементов, именно, как нужно мне, приходилось использовать __attribute__ ((__packed__)), что снижало скорость работы с данными структурами.

Еще по сабжу. protected: означает, что ты не сможешь обратиться к этим элементам снаружи класса. Отличие от private: состоит в том, что при protected: допускается обращение к этим элементам из унаследованного класса. Например:

Код:

class a { public: a(); int a1; protected: int a2; private: int a3; }; class b : public a; { public: b(); int a4; private: int a5; }; void a::a() { a1=0; //Можно a2=0; //Можно a3=0; //Можно } void b::b() { a1=1; //Можно a2=1; //Можно a3=1; //Нельзя a4=1; //Можно a5=1; //Можно } int main() { a *a_ex=new a; b *b_ex=new b; a_ex->a1=2; //Можно a_ex->a2=2; //Нельзя a_ex->a3=2; //Нельзя b_ex->a1=2; //Можно b_ex->a2=2; //Нельзя b_ex->a3=2; //Нельзя b_ex->a4=2; //Можно b_ex->a5=2; //Нельзя return 0; }
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

где можно почитать о том как работают классы на низком уровне, желательно чтобы не было привязано к одному конкретному языку, или хотя бы о механизме работы protected, это уже для c++?
_DG, я узнаю адрес нужной мне переменной. кстати почему может поменятся их порядок?
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

Потому что есть такая весч сделанная в целях оптимизации обращений к памяти, такой что

Код: Выделить всё

struct str_t
{
  int a;
  int b;
}

При этом sizeof(struct str_t)!=2*sizeof(int)


Подробностей, как и для чего организовано такое странное вырвние внутри структур я не помню (в info gcc подробно описано).

А порядок переменных внутри класса может поменяться хотя бы потому, что в спецификации языка C++, в отличии от C, нет четкого указания, что переменные и методы внутри экземпляра класса должны следовать именно в порядке их объявления. Поэтому компилятору никто не запрещает оптимизировать и группировать их как бог на душу положит. Причем разные компиляторы могут делать это по разному.

ЗЫ. Если нужно организовать плотноупакованную структуру, чтобы sizeof(struct str_t) из предыдущего примера была равна 2*sizeof(int) необходимо добавить в определение структуры __attrribute__ ((__packed__)), о чем я уже писал.
Спасибо сказали:
un-defined
Сообщения: 145
ОС: Kubuntu, Gentoo

Re: protected в C++

Сообщение un-defined »

А что понимается под работой классов на низком уровне без привязки к конкретному языку?
Don`t try - just do or do not ©Master Joda
Спасибо сказали:
Аватара пользователя
GRS
Сообщения: 236
Статус: C++ Pro
ОС: Suse10.2/XP

Re: protected в C++

Сообщение GRS »

или использовать дириктиву #pragma pack
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

#pragma pack работает на весь проект. А мой метод - только на ту структуру, к которой применен.
Поэтому в случае #pragma работа всего приложения, в случае обилия хитрых структур, заметно замедлится. А в случае __attribute__ ((__packed__)) работа почти не замедляется в силу оптимизации уже на уровне логики (например, основной целью применения данной директивы, является возможность использования быстрых memset/memcpy ко всей структуре вместо медленного явного присвоения значений каждому из ее элементов).
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

un-defined писал(а):
07.05.2008 11:46
А что понимается под работой классов на низком уровне без привязки к конкретному языку?

как они представляются в памяти.
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

wzrd писал(а):
07.05.2008 12:19
un-defined писал(а):
07.05.2008 11:46
А что понимается под работой классов на низком уровне без привязки к конкретному языку?

как они представляются в памяти.


Как решит компилятор. Я про это уже писал. Причем тот же gcc может совершенно по разному располагать этот класс в зависимости от использования -O2 -O3 или -OS
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: protected в C++

Сообщение sergio »

protected не имеет отношения ко времени выполнения программы. Это ограничение применяемое во время компиляции.
То, что вы спрашиваете - это классифицируется как "преднамеренное злодеяние", а от преднамеренных злодеяний никакой язык защищать не будет, ибо все равно надежной защиты от дураков не бывает, это аксиома. Поскольку си-си++ предоставляет прямой доступ к памяти и управление памятью, то возможна и запись в любую точку вашего адресного пространства, не защищенную от записи со стороны ОС. Защитить участок памяти от злобной записи кому-не-положено - эти задачи решает операционная система своими, системными, методами. К языкам отношения не имеет.
Если хотите, чтобы язык защищал вас от вас же самих от прямого доступа к памяти - выбирайте язык не дающий такого доступа (шел, перл, питон, ява, .....) Он всех остальных видов глупостей и злодеяний они вас, впрочем, все равно не защитят. :)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

_GV писал(а):
07.05.2008 11:12
Потому что есть такая весч сделанная в целях оптимизации обращений к памяти, такой что

Код: Выделить всё

struct str_t
 {
   int a;
   int b;
 }

 При этом sizeof(struct str_t)!=2*sizeof(int)

Это где вы такое нашли? У меня равно.

А вообще ничего обычно не меняется. Класс это обычная структура. Если в классе есть виртуальные методы, в нём появляется скрытый member - указатель на виртуальную таблицу. Методы класса — обычные методы с первым скрытым параметром this.

protected имеет значение только во время компиляции.
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

Код: Выделить всё

#include <stdio.h>
#include <string.h>

struct str_type
{
    int a,b;
    char c;
} str1;

int main (int argc,char **argv)
{
//    str1.a=1;
//    str1.b=2;
//    str1.c='q';
    printf("Sizeof struct == %d, sizeof sum == %d\n",sizeof (struct str_type),2*sizeof(int)+sizeof(char));
    return 0;
}

Код: Выделить всё

gcc qwertyuiop.c -o qwertyuiop


Код: Выделить всё

$./qwertyuiop
Sizeof struct == 12, sizeof sum == 9


ЗЫ. Прошу прощения. Конечно может быть и равно, но в общем случае - не факт. Именно это я и пытался сказать
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: protected в C++

Сообщение sergio »

v04bvs писал(а):
07.05.2008 12:44
_GV писал(а):
07.05.2008 11:12
Потому что есть такая весч сделанная в целях оптимизации обращений к памяти, такой что

Код: Выделить всё

struct str_t
 {
   int a;
   int b;
 }

 При этом sizeof(struct str_t)!=2*sizeof(int)

Это где вы такое нашли? У меня равно.


Пример неправильный у товарища. Его пример едва ли хоть на одной платформе даст "неравный" результат. Должно было быть что-нибудь вроде

Код: Выделить всё

struct str_t
 {
   int* зек1;
  char b;
   int* ptr2;
 }

И то, зависит от платформы и выравнивания, указанного компилеру.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

_GV писал(а):
07.05.2008 12:52
ЗЫ. Прошу прощения. Конечно может быть и равно, но в общем случае - не факт. Именно это я и пытался сказать

Ну это другое дело, здесь размер не кратен размеру слова. Просто размер структуры из 2 int-ов по-идее всегда будет равен 2 * sizeof(int).
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

sergio писал(а):
07.05.2008 12:53
v04bvs писал(а):
07.05.2008 12:44
_GV писал(а):
07.05.2008 11:12
Потому что есть такая весч сделанная в целях оптимизации обращений к памяти, такой что

Код: Выделить всё

struct str_t
 {
   int a;
   int b;
 }

 При этом sizeof(struct str_t)!=2*sizeof(int)

Это где вы такое нашли? У меня равно.


Пример неправильный у товарища. Его пример едва ли хоть на одной платформе даст "неравный" результат. Должно было быть что-нибудь вроде

Код: Выделить всё

struct str_t
 {
   int* зек1;
  char b;
   int* ptr2;
 }

И то, зависит от платформы и выравнивания, указанного компилеру.

вы имеете ввиду разрядность, т.е. кол-во байт необходимых для хранения адреса?
мне всё таки интересно почему происходит то что я описал в первом посте.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

wzrd писал(а):
07.05.2008 00:17
foo *ptr=new foo;
memset (ptr, 1, sizeof (foo) ); // это работает нормально
memset (ptr+(2*sizeof (int)), 2, sizeof (int)); //срабатывает исключение[code]
в синтаксисе мог и ошибиться, но думаю вопрос ясен. это я делал на borland' овском компиляторе. на gcc не пробывал.


ptr + (2 * sizeof(int)) = ptr + 8
ptr имеет тип foo*, поэтому ptr + 8 смещает указатель на ptr + 8 * sizeof(foo) байтов. Очевидно, это не то, что вы хотели.

Чтобы достичь желаемого, заведите переменную char*, прокастуйте foo* в неё и делайте что угодно.
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

Вообще такой подход к программированию на C++ назвается "экстремальным программированием" и крайне не одобряется. Так как при подобном подходе Ваш код будет совершенно несопровождаемым не только другими членами сообщества, но даже Вами самими, по прошествии некоторого (очень небольшого) времени. К тому же таким подходом Вы проявляете по меньшей мере неблагодарность к создателям этого языка и рекомендаций по стилевому оформлению кода.
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: protected в C++

Сообщение sergio »

_GV писал(а):
07.05.2008 14:15
Вообще такой подход к программированию на C++ назвается "экстремальным программированием" и крайне не одобряется. Так как при подобном подходе Ваш код будет совершенно неспровождаемым не только другими членами сообщества, но даже Вами самими, по прошествии некоторого (очень небольшого) времени. К тому же таким подходом Вы проявляете по меньшей мере неблагодарность создателям этого языка и рекомендаций по стилевому оформлению кода.


"Экстремальным программированием" (ХР) насколько мне известно, называется совсем иное. :rolleyes:
Человек не про практику программирования спрашивал, а исследовал законы языка и что защищает "защищенный" спецификтор доступа, имхо. ;)
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

_GV писал(а):
07.05.2008 14:15
Вообще такой подход к программированию на C++ назвается "экстремальным программированием" и крайне не одобряется. Так как при подобном подходе Ваш код будет совершенно несопровождаемым не только другими членами сообщества, но даже Вами самими, по прошествии некоторого (очень небольшого) времени. К тому же таким подходом Вы проявляете по меньшей мере неблагодарность к создателям этого языка и рекомендаций по стилевому оформлению кода.


Так программировать не нужно, но для того, чтобы разобраться "на низком уровне", почему бы и нет? А то есть некоторые товарищи, для которых классы, виртуальные методы/наследование, шаблоны и прочее, это что-то магическое и недоступное простым смертным.
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

а если сделать так? *(&ptr + 8)
я спрашиваю потому что нет рядом компилятора где бы я мог попробывать, но это вроде должно смешать правильно, или я ошибаюсь?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

wzrd писал(а):
07.05.2008 14:20
а если сделать так? *(&ptr + 8)
я спрашиваю потому что нет рядом компилятора где бы я мог попробывать, но это вроде должно смешать правильно, или я ошибаюсь?


Вообще фигня какая-то получится :)

((char*) ptr) + 8 нужно.
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

Я выше уже объяснил и привел подробный пример, что же означает атрибут protected: Но, тем не менее, мы вернулись к обсуждению откровенно некоректного примера, приведенного в заголовочном посте. А под "экстремальным программированием" я понимаю код, содержащий нетипичные для данного языка конструкции. Тем более, что, как я уже писал, в зависимости от компилятора, экземпляры класса могут оптимизироваться во внутреннем представлении по разному (нет в спецификации ограничений на это), следовательно вышеприведенный пример не будет переносим даже между различными компиляторами.
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

_GV писал(а):
07.05.2008 14:23
под "экстремальным программированием" я понимаю код, содержащий нетипичные для данного языка конструкции.

Общепринятое значение термина — применения ряда Agile методик при разработке ПО, и он относится к Project Management-у а не к программированию. Давайте будем употреблять слова в том значении, в котором их понимают все.

Тем более, что, как я уже писал, в зависимости от компилятора, экземпляры класса могут оптимизироваться во внутреннем представлении по разному (нет в спецификации ограничений на это), следовательно вышеприведенный пример не будет переносим даже между различными компиляторами.

Ну и что :)
Спасибо сказали:
Аватара пользователя
_GV
Сообщения: 107
Статус: секта красных утюгов
ОС: Gentoo linux

Re: protected в C++

Сообщение _GV »

Век живи - век учись.
Оказывается у меня было неправильное понимание термина "экстремальное программирование". Спасибо, что указали на ошибку.

Но тем не менее, все прочее, о чем я говорил, некорректно используя данный термин в силе
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

_GV писал(а):
07.05.2008 14:23
Я выше уже объяснил и привел подробный пример, что же означает атрибут protected: Но, тем не менее, мы вернулись к обсуждению откровенно некоректного примера, приведенного в заголовочном посте. А под "экстремальным программированием" я понимаю код, содержащий нетипичные для данного языка конструкции. Тем более, что, как я уже писал, в зависимости от компилятора, экземпляры класса могут оптимизироваться во внутреннем представлении по разному (нет в спецификации ограничений на это), следовательно вышеприведенный пример не будет переносим даже между различными компиляторами.

дело не в примере, а в вопросе. и вообще при чем тут непереносимость между компиляторами? зачем это нужно в данном случае?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: protected в C++

Сообщение v04bvs »

_GV писал(а):
07.05.2008 14:33
Но тем не менее, все прочее, о чем я говорил, некорректно используя данный термин в силе


Некорректно в том смысле, что не гарантирована работа на всех платформах и компиляторах, соблюдающих стандарт.
Корректно в том смысле, что на конкретном компьютере и конкретном компиляторе при конкретных опциях это будет работать.
Я вот когда-то исследовал виртуальные таблицы, руками делал свои и перезаписывал vtbl объекта. Было весело, можно было динамически изменять тип объекта. Ну и что, что не по стандарту, зато работает :D
Спасибо сказали:
Аватара пользователя
wzrd
Сообщения: 323
ОС: Debian Lenny

Re: protected в C++

Сообщение wzrd »

всем спасибо за помощь.
v04bvs, благодарю за подсказку насчет приведение указателя к нужному типу. именно в этом была пробема. достаточно: int *p = (int *) ptr;
Спасибо сказали: