Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Убрать функцию из интерфейса класса-потомка?  (Прочитано 867 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Дядюшка Ау

  • Автор темы
  • Участник
  • *
  • Сообщений: 123
  • Дайте две!
    • Просмотр профиля
Есть класс, в котором некоторый метод объявлен, как public. Можно ли унаследовать этот класс, чтобы из его интерфейса ушла данная функция. Т.е. стала как-бы private?
Ubuntu 12.04 для поколупацца, Win7 для поработать

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 754
    • Просмотр профиля
http://pastebin.com/meYQHQk8

[user@pc ~]$ g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:22: error: ‘void cl_2::publicMethod2()’ is private
test.cpp:32: error: within this context
[user@pc ~]$


Оффлайн actics

  • Новичок
  • *
  • Сообщений: 36
    • Просмотр профиля
Если я не ошибаюсь, можно просто спрятать вот так: (публичный вызов publicMethod2() из cl_2 в данном случаи невозможен)

#include <iostream>

class cl_1
{
public:
cl_1(void) {};
~cl_1() {};
void publicMethod1() {
std::cout << "cl_1::publicMethod1" << std::endl;
};
void publicMethod2() {
std::cout << "cl_1::publicMethod2" << std::endl;
};
};

class cl_2 : public cl_1
{
public:
cl_2(void) {};
~cl_2() {};
void test_print() {
cl_1::publicMethod2();
}
private:
void publicMethod2();
};

int main()
{
cl_1 m_cl_1;
cl_2 m_cl_2;
m_cl_2.publicMethod1();
m_cl_2.test_print();
return 0;
}
« Последнее редактирование: 24 Мая 2012, 06:05:20 от actics »

Оффлайн Дядюшка Ау

  • Автор темы
  • Участник
  • *
  • Сообщений: 123
  • Дайте две!
    • Просмотр профиля
На самом деле, мне тут один человек подсказал, что так делать низя-низя. И не потому что там какие-то технические детали, а потому, что класс-потомок отказывается от интерфейса родителя. Т.е. если в код клиента вместо родителя подсунуть потомка (полиморфизм), то код клиента думая, что работает с родителем, имеет полное право вызывать все его открытые методы. А тут он обламывается. Идеологическая диверсия.
Ubuntu 12.04 для поколупацца, Win7 для поработать

Оффлайн unimix

  • Активист
  • *
  • Сообщений: 537
    • Просмотр профиля
Для таких целей есть виртуальные методы =)

Код: (cpp) [Выделить]
    #include <iostream>
     
    class cl_1
    {
    public:
        cl_1(void) {};
        ~cl_1() {};
        void publicMethod1() {
                std::cout << "cl_1::publicMethod1" << std::endl;
        };
        virtual void publicMethod2() {
                std::cout << "cl_1::publicMethod2" << std::endl;
        };
    };
     
    class cl_2 : public cl_1
    {
    public:
        cl_2(void) {};
        ~cl_2() {};
    private:
        void publicMethod2() {
            std::cout << "cl_2::publicMethod2" << std::endl;
        };
    };
     
    int main()
    {
        cl_1* m_cl_2 = new cl_2();
        m_cl_2->publicMethod1();
        m_cl_2->publicMethod2();
        delete (cl_2*) m_cl_2;
        return 0;   
    }

update:
Поправил удаление объекта.
« Последнее редактирование: 24 Мая 2012, 19:17:36 от unimix »

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 754
    • Просмотр профиля
Но тогда cl_2::publicMethod2 public.
[user@pc ~]$ g++ test.cpp -o test
[user@pc ~]$ ./test
cl_1::publicMethod1
cl_2::publicMethod2
[user@pc ~]$

Можно, конечно, его переопределить, чтобы он выдавал сообщение типа "низзя"...

Оффлайн unimix

  • Активист
  • *
  • Сообщений: 537
    • Просмотр профиля
Но тогда cl_2::publicMethod2 public.

Замени
Код: (cpp) [Выделить]
cl_1* m_cl_2 = new cl_2()на
Код: (cpp) [Выделить]
cl_2* m_cl_2 = new cl_2()и увидишь, что метод publicMethod2 закрыт.

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 754
    • Просмотр профиля
Тоже самое получается, что я написал, только cl_1::publicMethod2 стал virtual. (Я пока плохо понимаю различие, знаю только что деструктор надо делать virtual, что я, кстати, забыл написать).

Оффлайн Vovaldo

  • Любитель
  • *
  • Сообщений: 82
  • Ху Тин Пуй
    • Просмотр профиля
    • Путин забрал у Медведева инновационный орган
На самом деле, мне тут один человек подсказал, что так делать низя-низя. И не потому что там какие-то технические детали, а потому, что класс-потомок отказывается от интерфейса родителя. Т.е. если в код клиента вместо родителя подсунуть потомка (полиморфизм), то код клиента думая, что работает с родителем, имеет полное право вызывать все его открытые методы. А тут он обламывается. Идеологическая диверсия.
Полный бред. Тогда бы в С++ и спецификатора private не было при наследовании родительского класса. А он, между прочим, вообще все его члены скроет - и public, и protected, и private.

Оффлайн Дядюшка Ау

  • Автор темы
  • Участник
  • *
  • Сообщений: 123
  • Дайте две!
    • Просмотр профиля
Да, но мне в моей задаче как раз нужно было, чтобы потомки и родители выглядели одинаково для кода клиента, но пара методов должна была как бы ничего не делать. Если бы я их скрыл, то получил бы логическую несогласованность при работе кода клиента, а то и падучесть при выполнении.

Короче, "Решено" и тема закрыта. Спасибо.
Ubuntu 12.04 для поколупацца, Win7 для поработать

 

Страница сгенерирована за 0.05 секунд. Запросов: 25.