C ++ как элегантно бороться с дружбой, не наследуя - PullRequest
2 голосов
/ 28 ноября 2011

У меня есть набор классов

class myClassA{
    friend class MyFatherClass;
};

class MyFatherClass{
    ...
};

class MySonClass : public MyFatherClass {
};

Мой класс отца может получить доступ ко всем методам класса MyClassA. Мне также хотелось бы, чтобы все классы, которые будут расширять MyFatherClass, могли вызывать такие методы.

Я вижу только 2 варианта:

  1. В любое время я добавляю в myClassA новый класс в качестве друга. (Мне это не нравится)
  2. Я создаю некоторую защищенную оболочку в функции отца для доступа к методу из класса myClassA. (немного лучше, но мне все еще не нравится это, потому что я должен создать новую оболочку в любое время, когда новый метод создается в myClassA)

Есть ли у вас идеи для более элегантного решения проблемы?

Спасибо

Ответы [ 2 ]

1 голос
/ 28 ноября 2011

Прежде всего ... что значит элегантный?Меньше кода для вас, чтобы написать?Я предлагаю вам не идти на компромисс, когда дело доходит до читабельности.

Использование дружбы не должно быть простым решением.На SO есть множество потоков, которые занимаются этим, но здесь я просто предполагаю, что вы уже знаете, что это означает.

Вариант 1) гораздо более читабелен.Когда кто-то видит класс, он сразу узнает, кто имеет к нему доступ.Код должен быть выразительным, и эта опция идеально описывает намерение.

Вариант 2) немного излишним.Вы пишете обертку только для того, чтобы вы могли получить доступ к некоторым функциям ... почему бы не сделать их public для начала, поскольку обертка имеет публичный доступ.Это просто дополнительный уровень абстракции для ничего.

Сначала вы должны подумать о функциональности (обе работы), выразительности и читабельности (вариант 1 здесь определенно лучше).

0 голосов
/ 28 ноября 2011

Немного сложно судить, зная так мало о приложении, но если функции только будут использоваться MyFatherClass и его потомками, они должны быть protected членами (возможно, static) из MyFatherClass.

Возможно, MyClassA должен быть членом MyFatherClass без собственных функций-членов, просто struct для хранения некоторых элементов данных.

class MyFatherClass {
protected:
    struct myStructA {
        int state;
    };

    static void DoSomething( myStructA &a );
    …
};

Просто предложение ... трудно сказать, что лучше всего дать так мало информации. Общая идея заключается в том, что язык запрещает friend наследование кораблей, потому что вы всегда можете сделать хороший дизайн без него.

...