Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499

Доступ к данным при наследовании

01.07.2016, 22:41. Показов 3415. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте, есть иерархия классов, схематично можно представить так:

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
namespace Singl {
class CObs {};
 
template<typename T>
class A {
public:
    virtual ~A() { delete variables; }
    static T* Instance() {
        if(variables)
            return variables;
        else
            return new T();
    }
 
protected:
    static T* variables;
    A() {}
};
 
template<typename T>
T* A<T>::variables = nullptr;
 
 
class B : public A<B> {
protected:
    B() {}
    std::vector<int> data;
};
 
class C : public B {
public:
    void foo(CObs*) {
        auto a = variables->data;
    }
};
}
проблема один : не может получить доступ к data из класса С ... можно ли что-то сделать кроме того, чтобы в В поле поменять на публичное?
проблема два : нужно вызвать метод фу без создания объекта С , возможно ли это сделать?
так не выходит:

C++
1
2
3
Singl::C::Instance();
    Singl::CObs obs;
    std::bind(&Singl::C::foo, Singl::C::Instance(), &obs)();
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.07.2016, 22:41
Ответы с готовыми решениями:

Доступ к переменным базового класса при наследовании
Есть следующий код class Base { protected: int x; Base* enemy; public: Base() {}

Доступ к объекту базового класса при закрытом наследовании
Есть класс Pair из стандартной библиотеки. Он у меня содержит 2 массива valarray. От класса Pair я создаю наследника Wine. В классе Wine...

Доступ к открытым методам базового класса при частном наследовании
Всем, привет, возникла проблема. Есть классы 1-&gt;2-&gt;3. Класс 2 явл наследником 1, а 3 класс является наследником 2. Все наследования...

20
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 00:13
Цитата Сообщение от tapochka Посмотреть сообщение
не может получить доступ к data из класса С ... можно ли что-то сделать кроме того, чтобы в В поле поменять на публичное?
1) friend
2) перенести ответственность за работу с data в функцию класса B.
Второе лучше.
Цитата Сообщение от tapochka Посмотреть сообщение
нужно вызвать метод фу без создания объекта С , возможно ли это сделать?
Т.е. метод объекта С вызвать без самого объекта С?
Если да, то нет, нельзя. Как ты себе вообще это представляешь?

Может расскажешь что это за система такая? Пока что выглядит подозрительно.
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 00:45  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Может расскажешь что это за система такая? Пока что выглядит подозрительно.
ну в общем А это синглтон от которого все наследуются, B - объект который должен быть создан лишь единожды ну и немного методов(виртуальных по-моему)... но я забыл написать, что С еще наследуется от иерархии интерфейсов, у которых виртуальные методы... и в этом вся запара: мы создаем С через статический метод Instance() , но виртуальные методы мы обязаны вызывать через объекты , а объекты мы создать не можем ,т.к. С так же наследуется от синглтона(конструктор не публичный)... и вот как быть то?)

Цитата Сообщение от DrOffset Посмотреть сообщение
Если да, то нет, нельзя. Как ты себе вообще это представляешь?
hoggy писал на форуме как то:
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
48
#include <iostream>
using namespace std;
 
// так как функции-члены на самом деле точно такие же "свободные функции"
// то технически, мы можем запустить функцию-член, не как метод класса
// а как самую обычную свободную функцию
// проиллюстрируем это:
 
 
struct Example
{
    // мы будем запускатьэтот метод не как метод, 
    // а как обычную свободную функцию
    void foo(int) { cout<<"Example::foo(int);\n"; }
};
 
int main()
{
    std::cout << "Hello, world!\n";
    
    typedef 
        void(*Free)(Example*, int);
    typedef 
        void(Example::*Method)(int);
    
    //для того, что бы запустить метод, как свободную функцию
    //нужно выполнить преобразования метода в свободную функцию
    
    Method m= &Example::foo;
    
    //для этого возьмем адрес функции-члена таким образом,
    //что бы компилятор забыл изначальный тип функции-члена
    //это позволит обойти защиту компилятора при некорректном 
    //с точки зрения компилятора преобразовании типов функции-члена к функции
    void* proxy = (void*)&m;
 
 
    //теперь извлекаем объект обратно, преобразовывая его тип к типу функции
    Free f = *((Free*)proxy);
    
    Example ex;
    
    
    //теперь, если наша теория верна, мы можем запустить функцию, 
    //передав первым аргументом тот самый "не видимый" параметр this
    //а следом все прочие аргуметы
    f(&ex,10);  
}
вот в этом духе как то, я правда сам не пробовал еще... потыкался с биндом и бросил
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 00:55
Цитата Сообщение от tapochka Посмотреть сообщение
вот в этом духе как то
Так в этом духе объект-то все равно должен быть. Единственная разница в способе извращенности при передаче указателя на экземпляр.

Добавлено через 2 минуты
Цитата Сообщение от tapochka Посмотреть сообщение
и вот как быть то?
Загнал себя в какие-то странные рамки, а теперь пытаешься выбраться
Ты можешь описать проблему, которую ты решаешь этим кодом?
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 00:58  [ТС]
DrOffset, вот по поводу первого вопроса: я понять не могу одно, а именно что у нас же data в B протектед а не приват... почему наследник от B не имеет доступ то?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 01:02
Цитата Сообщение от tapochka Посмотреть сообщение
почему наследник от B не имеет доступ то?
Вот именно, через protected имеет доступ только подобъект наследника, а не кто попало
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 01:05  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Ты можешь описать проблему, которую ты решаешь этим кодом?
ну в общем есть у нас сущность, которая должна быть создана при старте и в одном экземпляре на протяжении жизни программы жить и чтобы она могла свободно использоваться между логическими модулями ... поэтому мы унаследовали ее от синглтона вместо того чтобы сделать ее тупо глобальным объектом... так же сущность должна наследовать кучу методов от других интерфейсов... но дабы иерархия имела расширяемость я сделал так: саму сущность я не стал наследовать от синглтона а создал класс B(название образное) который инкапсулирует логику синглтона + добавляет немного своей, ну и мы наследуемся от B уже своей сущностью и там возимся с методами от интерфейсов, а логика от синглтона остается на плечах B... как то так
ну на самом деле там не один синглтон, а еще есть штуки... но я описал именно то, что я хотел достичь

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот именно, через protected имеет доступ только подобъект наследника, а не кто попало
чет я не допер... напишите, если не сложно, какой-нибудь простой кусок
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 01:14
Цитата Сообщение от tapochka Посмотреть сообщение
чет я не допер... напишите, если не сложно, какой-нибудь простой кусок
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A
{
protected:
    int a;
};
 
class B : public A
{
public:
    void foo(A * p)
    {
        this->a = 10; // подобъект базового класса
        p->a = 11;    // черт знает кто
    }
};
Добавлено через 2 минуты
Цитата Сообщение от tapochka Посмотреть сообщение
который инкапсулирует логику синглтона + добавляет немного своей, ну и мы наследуемся от B уже своей сущностью и там возимся с методами от интерфейсов
Так у тебя много синглтонов или один?
Что такое variables?
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 01:18  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Так у тебя много синглтонов или один?
я использую один, самый простой

Цитата Сообщение от DrOffset Посмотреть сообщение
Что такое variables?
ну это указатель на объект, который наследуется от этого синглтона
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 01:36
Цитата Сообщение от tapochka Посмотреть сообщение
ну это указатель на объект, который наследуется от этого синглтона
Просто у тебя он нигде не инициализируется, вот я и засомневался. Подумал, что это может быть массив объектов (множественное число в названии переменной), какой-то уклон в сторону пула.

Если пула нет, то в С++11 лучше пользоваться синглтоном Мейерса в таком случае.

Цитата Сообщение от tapochka Посмотреть сообщение
виртуальные методы мы обязаны вызывать через объекты, а объекты мы создать не можем
Теперь вот это поясни подробнее. Лучше с примером, пусть даже нерабочим.

Добавлено через 4 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Теперь вот это поясни подробнее.
Почему спрашиваю. Ты написал, что синглтон у тебя один только. Значит мне не понятно, почему не достаточно шаблона.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
class Singleton
{
public:
    static T & Instance() 
    {
        static T instance;
        return instance;
    }
 
protected:
    Singleton() {}
};
И передавать параметром сразу класс С. А то, ты передал B, создался соответственно объект типа B, а работать с ним хочешь как с С. Но на каком основании? Если тебе нужен С, то и создавай его так:
C++
1
2
3
4
class С : public Singleton<С>
{
//...........
};
Или сделай B тогда тоже шаблоном, что писать так:
C++
1
2
3
4
5
6
7
8
template <typename T>
class B : public Singleton<T>
{
};
 
class C : public B<C>
{
};
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 01:44  [ТС]
в общем думаю может
Цитата Сообщение от DrOffset Посмотреть сообщение
Теперь вот это поясни подробнее. Лучше с примером, пусть даже нерабочим.
вот есть код:
C++
1
2
3
4
Singl::C::Instance(); // создали объект 
Singl::C::some_method(); // этот метод от интерфейса пришел к нам, но его не получится так вызвать т.к. виртуальный
Singl::C c;
c.some_method();    //но так сделать не можем т.к. конструктор не публичный у C(чтобы нельзя было сколько угодно создавать объектов)
и на этом я заглох... хотел как нибудь через bind хаком каким-нибудь вызвать some_method, но увы

Добавлено через 6 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Значит мне не понятно, почему не достаточно шаблона.
ну потому что синглтон то уже есть и лучше его использовать(который много где используется)... а не плодить свои классы, где я могу накосячить,по крайней мере как мне объясняли
можно конечно на худой конец и синглтон майерса заюзать... или Александресковский )

Цитата Сообщение от DrOffset Посмотреть сообщение
И передавать параметром сразу класс С. А то, ты передал B
ну чтобы инкапсулировать всю логику работы с синглтоном в одном месте, а свой С уже в другом месте...

в общем надо будет думать еще
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 01:54
Цитата Сообщение от tapochka Посмотреть сообщение
хаком
Ну скасти, раз так хочется, static_cast`ом к С, да и все.
Только ведь это бред: вот к тебе пришла девушка Лена, а ты в самом интересном месте назвал ее Катей. Что с тобой будет после этого?

Цитата Сообщение от tapochka Посмотреть сообщение
через bind
В бинде никаких хаков нет. Он работает честно. Могу посоветовать только разобраться тогда как он работает, чтобы выбросить все иллюзии

Цитата Сообщение от tapochka Посмотреть сообщение
но его не получится так вызвать т.к. виртуальный
Его вызывать не получится, т.к. у тебя объект синглтона всегда B, независимо от того, кто там еще дальше наследовался. Естественно функциональность создаваемых объектом только им и ограничена.

Цитата Сообщение от tapochka Посмотреть сообщение
но так сделать не можем т.к. конструктор у не публичный у C
Не ну погоди. Что это за шаманство?
Если тебе нужно такое поведение, то зачем ты его запретил? Зачем вообще связался с этим мерзким антипаттерном "синглтон", раз тебе нужны отдельные объекты?

Добавлено через 1 минуту
Цитата Сообщение от tapochka Посмотреть сообщение
ну потому что синглтон то уже есть и лучше его использовать(который много где используется)... а не плодить свои классы, где я могу накосячить,по крайней мере как мне объясняли
можно конечно на худой конец и синглтон майерса заюзать... или Александресковский )
"Синглтон Мейерса" - это имя собственное для паттерна создания синглтона, а не готовый библиотечный код.
К тому же в коде выше ты уже раза два накосячил в синглтоне, который у тебя течет по памяти и не инициализируется добром

Добавлено через 7 минут
Цитата Сообщение от tapochka Посмотреть сообщение
ну чтобы инкапсулировать всю логику работы с синглтоном в одном месте, а свой С уже в другом месте...
Может тут паттерн стратегия больше подойдет?
Управляющий объект делаешь синглтоном, а потом всякие С, Д, Е классы передаешь ему в качестве поведенческих политик.
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 02:00  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Если тебе нужно такое поведение, то зачем ты его запретил? Зачем вообще связался с этим мерзким антипаттерном "синглтон", раз тебе нужны отдельные объекты?
ну вбили мне в свое время в голову, что глобальные объекты мешают расширяемости, тестируемости и т.д. к тому же есть синглтоны реализованные не мной, что код то дублировать?)

Цитата Сообщение от DrOffset Посмотреть сообщение
К тому же в коде выше ты уже раза два накосячил в синглтоне, который у тебя течет по памяти и не инициализируется добром
не, ну у B и C есть же деструкторы с delete variables то) просто не писал их

Цитата Сообщение от DrOffset Посмотреть сообщение
В бинде никаких хаков нет. Он работает честно. Могу посоветовать только разобраться тогда как он работает, чтобы выбросить все иллюзии
хотел я упрощенную версию написать сам... чтобы разобраться... в итоге забил пока что, все время уходит не понятно на что

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
Может тут паттерн стратегия больше подойдет?
Управляющий объект делаешь синглтоном, а потом всякие С, Д, Е классы передаешь ему в качестве поведенческих политик.
буду думать... как раз статейку находил https://xakep.ru/2010/11/01/53649/
название конечно чересчур громкое
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 02:03
Цитата Сообщение от tapochka Посмотреть сообщение
не, ну у B и C есть же деструкторы с delete variables то) просто не писал их
Ты вот возьми эти деструкторы и посмотри, вызываются они или нет

Цитата Сообщение от tapochka Посмотреть сообщение
ну вбили мне в свое время в голову, что глобальные объекты мешают расширяемости, тестируемости и т.д.
Правильно вбили. Синглтон в этом отношении ничем не лучше. Но я лишь хотел указать на дыру в рассуждениях. Тебе надо определиться: ты хочешь такси с шашечками или все-таки до места доехать.
Ты понял в чем ошибка?
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 02:09  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Ты понял в чем ошибка?
ошибка в том, что у меня опыта мало чтобы заранее все продумать, в итоге я как большевики в 18-м году по словам Троцкого: Чтобы научиться страной управлять, надо взять в руки правление... и на ходу все уже додумывать)
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.07.2016, 02:20
Лучший ответ Сообщение было отмечено tapochka как решение

Решение

Цитата Сообщение от tapochka Посмотреть сообщение
ошибка в том, что у меня опыта мало чтобы заранее все продумать, в итоге я как большевики в 18-м году по словам Троцкого: Чтобы научиться страной управлять, надо взять в руки правление... и на ходу все уже додумывать)
Ну, отсутствие опыта - это не ошибка. Это причина
А ошибка в том, что у тебя не тот объект создается, который тебе нужен. Тебе нужен С, а создается B. Вот и все.
Таким образом решение проблемы состоит в том, чтобы разработать такой механизм, который позволил бы получить все-таки С. При этом оставаясь синглтоном (раз уж так надо).
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <memory>
#include <iostream>
 
template <typename T>
class Singleton 
{
public:
    template <typename Policy>
    static T & instance() 
    {
        static T instance(std::make_unique<Policy>());
        return instance;
    }
 
protected:
    Singleton() {}
    
    Singleton(Singleton const &);
    Singleton & operator=(Singleton const &);
};
 
class BasePolicy
{
public:
    // interface
    
    virtual void foo() = 0;
};
 
 
class B : public Singleton<B>
{
public:
    explicit B(std::unique_ptr<BasePolicy> p)
        : m_policy(std::move(p))
    { }
    
    // proxy interface
    
    void foo()
    {
        m_policy->foo();
    }
    
private:
    std::unique_ptr<BasePolicy> m_policy;
};
 
class C : public BasePolicy
{
public:
    void foo()
    {
        std::cout << "foo\n";
    }
};
 
int main()
{
    B & inst = B::instance<C>();
    
    inst.foo();
}
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
02.07.2016, 02:27  [ТС]
благодарствую, буду возиться
на первый взгляд это кажись то что было нужно...
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
04.07.2016, 21:47  [ТС]
DrOffset, хм опробовал - не подходит... у класса С то конструктор нельзя сделать приватным, а это все убивает - сразу нету смысла тогда и в наследовании от синглтона
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
04.07.2016, 21:59
Цитата Сообщение от tapochka Посмотреть сообщение
у класса С то конструктор нельзя сделать приватным
Можно. Сделать другом создающую функцию синглтона:
C++
1
2
3
4
5
6
7
8
9
10
11
class C : public BasePolicy
{
    friend B & Singleton<B>::instance<C>();
public:
    void foo()
    {
    }
    
private:
    C() {}
};
Цитата Сообщение от tapochka Посмотреть сообщение
нету смысла тогда и в наследовании от синглтона
Может и нет. В этой схеме наследник синглтона является прокси-классом к политике поведения. Сам он синглтон, что делает политику тоже синглтоном. Т.е. в этом отношении наследование от синглтона нужно, чтобы сделать класс B синглтоном, т.к. он предоставляет основной интерфейс. При этом сам класс синглтона подразумевается где-то в библиотечном\утилитном коде проекта.
Если тебе нужно что-то другое, то задачу надо переформулировать - ибо тогда не ясно что опять не подходит
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
05.07.2016, 21:53  [ТС]
DrOffset, все нормально, спасибо за помощь... в общем тупо зафрендил std::make_unique и дело в шляпе... костылище правда еще тот
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.07.2016, 21:53
Помогаю со студенческими работами здесь

Получить доступ к методу, который при наследовании стал private
Как получить доступ к методу, который при наследование стал private ?

Получить доступ из класса к переменной при наследовании
using System; class a { public int x = 90; } class b : a { public int x = 110; } class c : b

Доступ к данным при selType: 'cellmodel'/'rowmodel'
Доброго времени суток. Когда в гриде задано selType: 'rowmodel', т.е. тип выделения контента по умолчанию - доступ к данным для...

Доступ к данным из SQL при клике по строке в DataGridView
Проект Windows Forms @ C# Имеется табличка (далее SQLTable) в базе данных SQL (SQL). Имеется DataGridView (DGV), к которой привязана...

Есть ли возможность контролировать доступ флэшкам у которых есть доступ к данным через Security.allowDomain()
Есть задача: Локальная флэшка на компьютере работает и доступа для правки к ней не имею . Любая флэшка запущенная в браузере, с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru