1. Требуются разработчики и тестеры для проекта codebyOS. Требования для участия в проекте: Знание принципов работы ОС на базе Linux; Знание Bash; Крайне желательное знание CPP, Python, Lua; Навыки системного администрирования. Подробнее ...

    Скрыть объявление

Наследование

Тема в разделе "Общие вопросы по С и С++", создана пользователем Stashevckiy, 13 ноя 2011.

  1. Stashevckiy

    Stashevckiy Well-Known Member

    Репутация:
    0
    Регистрация:
    23 окт 2011
    Сообщения:
    56
    Симпатии:
    0
    Привет! Подскажите, пожалуйста, как из производного класса получить значение private - переменной базового класса? Спасибо!
     
  2. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Это не допустимо, можно получить доступ только к protected и public.

    Можно сделать вот так:
    Код:
    #include <iostream>
    
    using namespace std;
    
    class A {
    friend class B;
    private:
    int		a;
    };
    
    class B : public A
    {
    public:
    void test() {
    A	a;
    a.a = 10;
    cout << a.a << endl;
    }
    };
    
    int main()
    {
    B	x;
    x.test();
    return 0;
    }
    это не совсем то что ты хотел, тут доступ к private-члену осуществляется посредством объявления класса B дружественным.
     
  3. Stashevckiy

    Stashevckiy Well-Known Member

    Репутация:
    0
    Регистрация:
    23 окт 2011
    Сообщения:
    56
    Симпатии:
    0
    просто вот что именно меня интересует. Есть такого рода задача : реализация паттерна Посредник. К примеру, есть 4 класса -> User, Mediator, ClassA, ClassB. Обьект User принимает строку. И мне нужно эту строку, которую получил обьект User передать в ClassA, ClassB посредством класса Mediator. По идее же, паттерн посредник подразумевает наслевоние.. Задачу эту я сделал, но чуть схитрив, а так не интересно.

    Собственно, вот программа.

    Здесь при создании обьекта User происходит вызов обьекта Mediator и передача ему указателя на строку( ну или же строки, чтобы понятней было). Конструктор класса Mediator в свою очередь вызывает конструктор класса ClassA, и через указатель передает в него строку, полученную классом Mediator, и здесь же происходит передача этой строки в класс B, но посредством использования композиции...А это вроде не круто как - то )) Вот такие дела..


    Код:
    #ifndef USER_H
    #define USER_H
    
    class User : public Mediator
    {
    public: 
    User( const char * = 0 );
    
    private:
    char * temp;
    };
    
    User::User(const char * variable):Mediator( variable )
    {
    temp = new char [ strlen(variable) + 1 ];
    strcpy( temp, variable );
    cout<<"\C_User ---> "<<temp<<"\n"<<endl;
    }
    #endif
    
    #ifndef MEDIATOR_H
    #define MEDIATOR_H
    
    #include "ClassB.h"
    
    class Mediator: public ClassA
    {
    public:
    Mediator( const char * = 0);
    ClassB obj;
    
    private:
    char * storage;
    };
    
    Mediator::Mediator(const char * variable) : ClassA ( variable)
    {
    storage = new char [ strlen(variable) + 1 ];
    strcpy( storage, variable);
    obj.setTT(variable);
    }
    #endif
    
    #ifndef CLASSA_H
    #define CLASSA_H
    
    #include "iostream"
    using namespace std;
    
    class ClassA
    {
    public:
    ClassA( const char * = 0);
    char * var;
    };
    
    ClassA::ClassA( const char * temp)
    {
    var = new char [ strlen(temp) + 1 ];
    strcpy(var, temp);
    cout<<"ClassA ---> "<<var<<"\n"<<endl;
    }
    #endif
    
    #ifndef CLASSB_H
    #define CLASSB_H
    
    #include "iostream"
    using namespace std;
    
    class ClassB
    {
    public:
    ClassB( const char * = 0);
    void setTT( const char * );
    
    private:
    char * tt;
    };
    
    ClassB::ClassB( const char * temp)
    {
    }
    void ClassB::setTT(const char * v)
    {
    tt = new char [ strlen(v) + 1 ];
    strcpy(tt, v);
    cout<<"\ClassB ---> "<<tt<<"\n"<<endl;
    }
    #endif
    
    #include "iostream"
    using namespace std;
    
    #include "ClassA.h"
    #include "ClassB.h"
    #include "Mediator.h"
    #include "User.h"
    
    void main()
    {
    User u("You don't like - you don't buy!");
    }

    А как сделать так, чтобы композицию заменить наследованием, я ума не приложу. Если пронаследовать классом claasB класс Mediator, то происходить ошибка, в которой говорится, что невозможно определить базовый класс ((
    Наследование
     
  4. rrrFer

    rrrFer Гость

    Репутация:
    0
    много кода, я невчитывался - попробуй сжать(оставь самое главное).
    Зато вчитался в первый пост:
    1. Получить значение можно при помощи public метода, например.
    Код:
    class A{
    /...
    public:
    int getVar();
    private:
    int var;
    //...
    };
    int A ::getVar() {
    return var;
    }
    
    calss B: public A {
    //...
    };
    В примере для того, чтобы "получить значение private - переменной базового класса" класса B(базовый А) нужно вызвать метод getVar().

    2. Если нужен полноценный доступ к полю базового класса - используй protected.

    3. Вариант лазибиз тоже выход, но дружбу я бы не использовал. С некоторых точек зрения она нарушает принцип инкапсуляции(в словесных баталиях на эту тему я участвовать не буду), хотя иногда без нее не обойтись(но вряд-ли это ваш случай).
     
  5. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Я вообще не понимаю зачем тебе член класса private делать. Думаю что лучше всего будет:
    Код:
    #include <iostream>
    
    using namespace std;
    
    class A {
    protected:
    int	x;
    };
    
    class B : public A {
    public:
    B( int v ) { x = v; }
    void print() {
    cout << x << endl;
    }
    };
    
    int main()
    {
    B	b( 123 );
    b.print();
    return 0;
    }
     
  6. Stashevckiy

    Stashevckiy Well-Known Member

    Репутация:
    0
    Регистрация:
    23 окт 2011
    Сообщения:
    56
    Симпатии:
    0
    Товарищи, почему же ни кто не хочет прочитать второй пост и вникнуть в суть поставленной задачи... Смотрите, что нужно организовать:

    1) Явно создать и инициализировать объект класса User.
    2) Получить значение обьекта User и сохранить в классе MEdiator - посредник.
    3) Получить сохраненное значение обьекта User из класса Mediator и сохранить в классе classA
    4) Получить сохраненное значение обьекта User из класса Mediator и сохранить в классе classB

    Я согласен, что не обязательно использовать private, но меня интересует, как реализовать выше перечисленные пункты при явной инициализации только обьекта User. Получится ли получить значение переменной из класса User в класс Mediator и последующие, если не создается явно обьекты последних, а в этих классах описан только процесс доступа к соответствующим переменным???
     
  7. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Держи.
    Код:
    #include <iostream>
    
    using namespace std;
    
    class User {
    friend class Mediator;
    public:
    User( int v ) { x = v; }
    private:
    int	x;
    };
    
    class Mediator {
    friend class ClassA;
    friend class ClassB;
    public:
    void getUser( User U ) { x = U.x; };
    protected:
    int	x;
    };
    
    class ClassA {
    public:
    void getMediator( Mediator M ) { x = M.x; };
    void print() { cout << x << endl; }
    protected:
    int	x;
    };
    
    class ClassB {
    public:
    void getMediator( Mediator M ) { x = M.x; };
    void print() { cout << x << endl; }
    protected:
    int	x;
    };
    
    int main()
    {
    User		U( 123 );
    Mediator	M;
    ClassA		A;
    ClassB		B;
    
    M.getUser( U );
    A.getMediator( M );
    B.getMediator( M );
    
    A.print();
    B.print();
    
    return 0;
    }
    Добавлено: Полностью подходит под твое описание.
     
  8. Stashevckiy

    Stashevckiy Well-Known Member

    Репутация:
    0
    Регистрация:
    23 окт 2011
    Сообщения:
    56
    Симпатии:
    0
    о, спасибо за пример! Сейчас попробую разобраться. Выглядит не сложно ;)
     
  9. Stashevckiy

    Stashevckiy Well-Known Member

    Репутация:
    0
    Регистрация:
    23 окт 2011
    Сообщения:
    56
    Симпатии:
    0
    Все получилось. Переделал под работу со строками. lazybiz, а скажи ка, если бы нужно было реализовать подобную задачу на API, т.е. при роботе с окнами, ты бы тоже использовал композицию, или в API есть по изощренней методы для такого рода задач?
     
  10. rrrFer

    rrrFer Гость

    Репутация:
    0
    зачем нам нужен посредник в данном случае?
    прочитал это:
    как я понимаю суть в том что есть N-потребителей, которых работают не с самим источником информации, а с посредником. Зачем? - наверно источники информации могут меняться(например, вводил пользователь данные клавиатурой, а начал вводить голосом), тогда при взаимодействии потребителя с источником напрямую, на потребителя возлагается задача определения "правильного" источника. Ну а тут предлагается решить 1 раз эту проблему посреднику, а потребителям использовать решение.

    Ну это мои предположения. Если я все верно понял - то изощренных средств в АПИ не знаю, но в QT есть удобный механизм сигналов и слотов.
    Для решения надо создать класс Посредник и класс Потребитель.
    в Посредник добавляем слот для получения данных от источника. Слот- это функция, которая вызывается по сигналу о приходе данных. в Посрденик добавляем сигнал для оповещения потребителей о том, что новые данные пришли и успешно сохранены в Посреднике.
    в Потребитель добавляем слот для получения данных от Посредника.

    все это соединяем методом connect примерно так:
    Код:
    Посредник Пс1;
    Потребитель Пт1, Пт2;
    connect( Некоторая_Кнопка, SIGNAL(pressed()), Пс1, SLOT(Прием_данных()));
    connect( Пс1, SINGAL(данные_сохранены_посредником()), Пт1, SLOT(Новые_данные())); 
    connect( Пс1, SINGAL(данные_сохранены_посредником()), Пт2, SLOT(Новые_данные()));
    как то так.
     
  11. lazybiz

    lazybiz Well-Known Member

    Репутация:
    0
    Регистрация:
    3 ноя 2010
    Сообщения:
    1.339
    Симпатии:
    0
    Если честно, то я вообще не понял что должна делать твоя программа, а просто дал тебе то что ты просил.
    О каких API и про какую композицию ты говоришь?
     
Загрузка...
Похожие Темы - Наследование
  1. pingvin-olia-23
    Ответов:
    1
    Просмотров:
    279
  2. Dragon108
    Ответов:
    23
    Просмотров:
    5.859
  3. vladis222
    Ответов:
    4
    Просмотров:
    1.695
  4. vladis222
    Ответов:
    4
    Просмотров:
    2.050
  5. olimp72
    Ответов:
    2
    Просмотров:
    2.516

Поделиться этой страницей