Форум программистов, компьютерный форум CyberForum.ru

Реализовать доступ к закрытой переменной - C++

Восстановить пароль Регистрация
 
linq
1 / 1 / 0
Регистрация: 05.11.2012
Сообщений: 26
23.12.2012, 09:41     Реализовать доступ к закрытой переменной #1
Можно ли в C++ получить доступ к закрытым переменным из класса Two в классе One, без изменения One? На сколько я знаю, друзей можно объявлять только в самом классе.(One)
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
class One
{
    private:
        int X;
}
class Two
{
    public:
    private:
}

На java это примерно так:
Кликните здесь для просмотра всего текста

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.lang.reflect.*;
class One
{
    private int X = 0;
}
public class JavaApplication1
{
    public static void main(String args[])
            throws NoSuchFieldException, IllegalAccessException
    {
            One one = new One();
            Field field = one.getClass().getDeclaredField("X");
            field.setAccessible(true);
            field.set(one, 1);
            System.out.println("X = " + field.get(one));
    }    
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
23.12.2012, 09:50     Реализовать доступ к закрытой переменной #2
Если нужно получить значение закрытого поля - пишем геттер. В соседнюю тему не вчитывался.
linq
1 / 1 / 0
Регистрация: 05.11.2012
Сообщений: 26
23.12.2012, 09:52  [ТС]     Реализовать доступ к закрытой переменной #3
Не заметил её.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
23.12.2012, 09:58     Реализовать доступ к закрытой переменной #4
Си++ в отличие от Джавы не умеет рефлексию. Даже если вам очень капец как надо залезть в кишки классу One, ничего при этом к нему не дописав, то всё равно надо как-то вытащить оттуда смещение этого поля, чтобы можно было по указателю до него добраться (offsetof, естессно, не сработает). Так что без сотрудничества класса One вы можете менять там всё только на свой страх и риск (ошиблись со смещением — сами виноваты).
SummerRain
 Аватар для SummerRain
325 / 324 / 17
Регистрация: 16.12.2012
Сообщений: 544
23.12.2012, 13:03     Реализовать доступ к закрытой переменной #5
скорее всего это не возможно, ибо противоречит принципам ООП.
v.a.l.i.d
 Аватар для v.a.l.i.d
412 / 377 / 10
Регистрация: 21.09.2012
Сообщений: 913
23.12.2012, 13:16     Реализовать доступ к закрытой переменной #6
вот как пример. для этого класса работает)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "stdafx.h"
#include "iostream"
using namespace std;
 
class One
{
public:
    One(int n)  { x = n; }
    int GetX()  { return x; }
private:
    int x;
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    One one(5);
    int *ptr_int = (int *)&one;
 
    cout << one.GetX()  << endl;
    *ptr_int = 555;                 // изменение закрытой переменной
    cout << one.GetX() << endl;
 
    system("pause");
    return 0;
}
SummerRain
 Аватар для SummerRain
325 / 324 / 17
Регистрация: 16.12.2012
Сообщений: 544
23.12.2012, 13:23     Реализовать доступ к закрытой переменной #7
Цитата Сообщение от v.a.l.i.d Посмотреть сообщение
вот как пример. для этого класса работает)
хм... а если бы там было много переменных?
WhiteP
605 / 203 / 23
Регистрация: 20.11.2012
Сообщений: 419
23.12.2012, 13:33     Реализовать доступ к закрытой переменной #8
Без dirty hacks - никак без изменения класса. А по смещениям - нужно многое учитывать (выравнивание, наследование, vtables)...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
 
class One
{
    int x;
public:
    One(int a):x(a){}
};
 
class Two
{
    int x;
public:
    virtual int Sum(int a)
    {
        return a+x;
    }
 
    Two(int a):x(a){}
};
 
class Three
{
    char a;
    int b;
public:
    Three(int x, char y):a(y), b(x){}
};
 
int main()
{
    One one(2888888888);
    Two two(1561561561);
    Three three(1231231231, (char)38);
 
    std::cout<<*(unsigned int*)&one<<std::endl;
    std::cout<<((unsigned int*)&two)[1]<<std::endl;
    std::cout<<((unsigned int*)&three)[1]<<std::endl;
 
    return 0;
}
v.a.l.i.d
 Аватар для v.a.l.i.d
412 / 377 / 10
Регистрация: 21.09.2012
Сообщений: 913
23.12.2012, 13:53     Реализовать доступ к закрытой переменной #9
Цитата Сообщение от SummerRain Посмотреть сообщение
а если бы там было много переменных?
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
надо как-то вытащить оттуда смещение этого поля, чтобы можно было по указателю до него добраться
вот что получилось для класса с тремя переменными:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "stdafx.h"
#include "iostream"
using namespace std;
 
class One
{
public:
    One(int i, float f, double d)       { x = i; y = f; z = d;}
    int GetX()      { return x; }
    float GetY()    { return y; }
    double GetZ()   { return z; }
private:
    int x;
    float y;
    double z;
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    One one(3, 4, 5);
    int *ptr_int       = (int *)&one;
    float *ptr_float   = (float *)(ptr_int + 1);
    double *ptr_double = (double *)(ptr_float + 1);
 
    cout << one.GetX() << " " << one.GetY() << " " << one.GetZ()  << endl;
    
    *ptr_int = 555;                 // изменение закрытых переменных
    *ptr_float = 666;
    *ptr_double = 777;
 
    cout << one.GetX() << " " << one.GetY() << " " << one.GetZ()  << endl;
 
    system("pause");
    return 0;
}
SummerRain
 Аватар для SummerRain
325 / 324 / 17
Регистрация: 16.12.2012
Сообщений: 544
23.12.2012, 14:12     Реализовать доступ к закрытой переменной #10
Цитата Сообщение от v.a.l.i.d Посмотреть сообщение
вот что получилось для класса с тремя переменными:
понятно. Даже не задумывался об этом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.12.2012, 14:16     Реализовать доступ к закрытой переменной
Еще ссылки по теме:

C++ Создать класс калькулятора Calc с закрытой переменной accumulator и с интерфейсом
Почему есть доступ к закрытой переменной класса C++
C++ Доступ к переменной из другого модуля

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
23.12.2012, 14:16     Реализовать доступ к закрытой переменной #11
Вот эти все + 1 это замечательно, но это, как сказано, dirty hacks. Вы не можете наверняка сказать, где в памяти будет размещено то или иное поле. Потому что выравнивание, потому что куда-то надо пристроить vtable, куда-то пристроить указатели на родителя при виртуальном наследовании, учесть данные родительского класса и т. п. Поэтому вот эти (float*)((int*)(&obj) + 1) — это стрельба по ногам, укрытым одеялом. Сегодня повезёт, а завтра мизинец прострелите.

Лучше уж делайте полноценного Паблика Морозова:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
 
class One {
private:
    class Public;
public:
    One(int i, float f, double d) : x(i), y(f), z(d) {}
    int    GetX() { return x; }
    float  GetY() { return y; }
    double GetZ() { return z; }
    
    Public please() { return Public(x, y, z); }
private:
    int    x;
    float  y;
    double z;
 
    class Public {
        friend class One;
    public:
        int    x() { return x_; }
        float  y() { return y_; }
        double z() { return z_; }
        void set_x(int    value) { x_ = value; }
        void set_y(float  value) { y_ = value; }
        void set_z(double value) { z_ = value; }
    private:
        Public(int &x_, float &y_, double &z_) : x_(x_), y_(y_), z_(z_) {}
        int    &x_;
        float  &y_;
        double &z_;
 
        // ибо нехер
        Public(const Public &o) : x_(o.x_), y_(o.y_), z_(o.z_) {}
        Public& operator=(const Public &o) { x_ = o.x_; y_ = o.y_; z_ = o.z_; return *this;}
    };
};
 
int main()
{
    One foo(1, 2, 3);
    std::cout << foo.GetY() << "\n";
    
    foo.please().set_y(5);
    
    std::cout << foo.GetY() << "\n";
}
Вот только возникает вопрос, чем это лучше
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
 
class One {
private:
    class Public;
public:
    One(int i, float f, double d) : x(i), y(f), z(d) {}
    int    GetX() { return x; }
    float  GetY() { return y; }
    double GetZ() { return z; }
    void SetX(int    value) { x = value; }
    void SetY(float  value) { y = value; }
    void SetZ(double value) { z = value; }
private:
    int    x;
    float  y;
    double z;
};
 
int main()
{
    One foo(1, 2, 3);
    std::cout << foo.GetY() << "\n";
    
    foo.SetY(5);
    
    std::cout << foo.GetY() << "\n";
}
Yandex
Объявления
23.12.2012, 14:16     Реализовать доступ к закрытой переменной
Ответ Создать тему
Опции темы

Текущее время: 08:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru