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

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

  1. Stashevckiy

    Stashevckiy Well-Known Member

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

    lazybiz Well-Known Member
    C\C++ Team

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

    Можно сделать вот так:
    Код (C++):
    #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

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

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

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


    Код (C++):
    #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, то происходить ошибка, в которой говорится, что невозможно определить базовый класс ((
    screen.png
     
  4. rrrFer

    rrrFer Well-Known Member
    Команда форума C\C++ Team

    Регистрация:
    6 сен 2011
    Сообщения:
    1.324
    Симпатии:
    36
    много кода, я невчитывался - попробуй сжать(оставь самое главное).
    Зато вчитался в первый пост:
    1. Получить значение можно при помощи public метода, например.
    Код (C++):
    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
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Я вообще не понимаю зачем тебе член класса private делать. Думаю что лучше всего будет:
    Код (C++):
    #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

    Регистрация:
    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
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Держи.
    Код (C++):
    #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

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

    Stashevckiy Well-Known Member

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

    rrrFer Well-Known Member
    Команда форума C\C++ Team

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

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

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

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Если честно, то я вообще не понял что должна делать твоя программа, а просто дал тебе то что ты просил.
    О каких API и про какую композицию ты говоришь?
     
Загрузка...
Похожие Темы - Наследование
  1. Dragon108
    Ответов:
    23
    Просмотров:
    5.536
  2. vladis222
    Ответов:
    4
    Просмотров:
    1.621
  3. vladis222
    Ответов:
    4
    Просмотров:
    1.926
  4. olimp72
    Ответов:
    2
    Просмотров:
    2.441
  5. xKlonx
    Ответов:
    2
    Просмотров:
    3.458

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