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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
linq
1 / 1 / 0
Регистрация: 05.11.2012
Сообщений: 26
#1

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

23.12.2012, 09:41. Просмотров 600. Ответов 10
Метки нет (Все метки)

Можно ли в 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));
    }    
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.12.2012, 09:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Реализовать доступ к закрытой переменной (C++):

Почему есть доступ к закрытой переменной класса - C++
Привет. Я уже было находил ответ на свой вопрос, но забыл :( Вопрос такой: есть след. класс: class Test { public: void F(Test t) {...

Создать класс калькулятора Calc с закрытой переменной accumulator и с интерфейсом - C++
Самостоятельно создать класс калькулятора Calc с закрытой переменной accumulator и с интерфейсом (открытыми функциями): void...

Виртуальные функции, как получить доступ к закрытой части класса.Через set-get? - C++
Здравствуйте! Мне очень нужна ваша помощь. Есть вот такой код. Но мне нужно получить доступ к базовому классу var, он же приватный через...

Получить доступ к переменной класса при наличии такого же имени переменной в функции - C++
Например, есть приватная переменная clientName в классе. Также есть точно такая же переменная в конструкторе этого класса. И мне нужно...

доступ к структурной переменной - C++
Эм, возникло небольшое недопонимание происходящего, а именно ошибка при компиляции программы следующего вида: #include <iostream> ...

Доступ к переменной из разных файлов - C++
есть 2 класса описанных в файле class.cpp и их заголовок в class.h, нужно добавить переменную статическую переменную (bool...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
0x10
2460 / 1632 / 238
Регистрация: 24.11.2012
Сообщений: 4,015
23.12.2012, 09:50 #2
Если нужно получить значение закрытого поля - пишем геттер. В соседнюю тему не вчитывался.
linq
1 / 1 / 0
Регистрация: 05.11.2012
Сообщений: 26
23.12.2012, 09:52  [ТС] #3
Не заметил её.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
23.12.2012, 09:58 #4
Си++ в отличие от Джавы не умеет рефлексию. Даже если вам очень капец как надо залезть в кишки классу One, ничего при этом к нему не дописав, то всё равно надо как-то вытащить оттуда смещение этого поля, чтобы можно было по указателю до него добраться (offsetof, естессно, не сработает). Так что без сотрудничества класса One вы можете менять там всё только на свой страх и риск (ошиблись со смещением — сами виноваты).
SummerRain
326 / 325 / 17
Регистрация: 16.12.2012
Сообщений: 544
23.12.2012, 13:03 #5
скорее всего это не возможно, ибо противоречит принципам ООП.
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
326 / 325 / 17
Регистрация: 16.12.2012
Сообщений: 544
23.12.2012, 13:23 #7
Цитата Сообщение от v.a.l.i.d Посмотреть сообщение
вот как пример. для этого класса работает)
хм... а если бы там было много переменных?
WhiteP
606 / 204 / 23
Регистрация: 20.11.2012
Сообщений: 426
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
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
326 / 325 / 17
Регистрация: 16.12.2012
Сообщений: 544
23.12.2012, 14:12 #10
Цитата Сообщение от v.a.l.i.d Посмотреть сообщение
вот что получилось для класса с тремя переменными:
понятно. Даже не задумывался об этом.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 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";
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.12.2012, 14:16
Привет! Вот еще темы с ответами:

Доступ к переменной из другого файла - C++
Не подскажете как получить доступ к переменной &quot;a&quot;? // Header.h namespace x1 { /* Объявление функций */ }

Доступ к переменной родительского класса - C++
Добрый день, уважаемые форумчане, изучаю классы в с++, есть вопрос: можно ли вызвать public функцию или переменную родительского класса...

Доступ к статической переменной-члену - C++
Всем доброго время суток задали написать программу, в которой доступ к статической переменной-члену осуществляется с помощью статической...

Доступ к переменной из другого модуля - C++
Среда разработки VS10 Express Есть модули: Main - главный модуль Other - подключаемый модуль Main.cpp


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
23.12.2012, 14:16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru