C ++ классы друзей - PullRequest
       22

C ++ классы друзей

6 голосов
/ 18 апреля 2009

Я понимаю, что есть много вопросов относительно классов друзей в C ++. Мой вопрос, однако, связан с конкретным сценарием. Учитывая приведенный ниже код, уместно ли использовать друга таким образом?

class Software
{
    friend class SoftwareProducer;

    SoftwareProducer* m_producer;
    int m_key;
    // Only producers can produce software
    Software(SoftwareProducer* producer) : m_producer(producer) { }

public:
    void buy()
    {
        m_key = m_producer->next_key();
    }
};

class SoftwareProducer
{
    friend class Software;

public:
    Software* produce()
    {
        return new Software(this);
    }

private:
    // Only software from this producer can get a valid key for registration
    int next_key()
    {
        return ...;
    }
};

Спасибо,

С уважением,

Ответы [ 4 ]

8 голосов
/ 18 апреля 2009

Конечно, это совершенно разумно. В основном то, что вы сделали, очень похоже на фабричный шаблон. Я не вижу никаких проблем с этим, поскольку ваш код, по-видимому, подразумевает, что каждый объект Software должен иметь указатель на своего создателя.

Хотя, как правило, вы можете избежать использования классов «Manager», таких как SoftwareProducer, и просто использовать статические методы в Software. Так как кажется вероятным, что будет только один SoftwareProducer. Возможно, что-то вроде этого:

class Software {
private:
    Software() : m_key(0) { /* whatever */ }
public:
    void buy() { m_key = new_key(); }
public:
    static Software *create() { return new Software; }
private:
    static int new_key() { static int example_id = 1; return example_id++; }
private:
    int m_key;
};

Тогда вы можете просто сделать это:

Software *soft = Software::create();
soft->buy();

Конечно, если вы планируете иметь более одного объекта SoftwareProducer, то то, что вы сделали, кажется уместным.

2 голосов
/ 18 апреля 2009

Мне кажется, это вполне разумно.

Проверьте Фабрики: инкапсулирование создания объекта от Брюса Эккеля Мышление в C ++ для получения дополнительной информации об этом конкретном использовании друзей.

Вы также можете посмотреть C ++ FAQ о друзьях , чтобы узнать больше эмпирических правил.

1 голос
/ 18 апреля 2009

Я не буду обсуждать вопрос дружбы, но мне не нравятся циклические зависимости. Программное обеспечение зависит от SoftwareProducer, которое зависит от самого программного обеспечения ... Я бы попытался провести рефакторинг.

Также обратите внимание, что дружеские отношения открывают внутренние органы для всех экземпляров другого класса. Это все равно что сказать, что ваш комментарий в next_key неверен:

Создание next_key private запрещает любому классу вызывать его, но как только вы откроете класс Software , любое программное обеспечение может вызвать next_key на всех SoftwareProducers .

1 голос
/ 18 апреля 2009

Я считаю приемлемым сделать SoftwareProducer в качестве друга Software, но я не вижу причин, по которым Software должен быть другом класса SoftwareProducer. Это ненужная зависимость между ними. Вы можете взять ключ в качестве аргумента конструктора для класса Software. Также вы можете захотеть сделать деструктор класса Software закрытым, чтобы никто, кроме SoftwareProducer, не мог их уничтожить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...