简体   繁体   中英

C++ friend classes

I realize that there are a lot of questions regarding friend classes in C++. My question, though, is tied to a specific scenario. Given the below code, is it appropriate to use friend in such a manner?

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 ...;
    }
};

Thanks,

Best regards,

Sure, that's perfectly reasonable. Basically what you have done is very similar to a factory pattern. I see no issue with that since your code seems to imply that every Software object should have a pointer to its creator.

Though, usually you can avoid to have "Manager" classes like SoftwareProducer, and just have static methods in Software. Since it seems likely that there will be only one SoftwareProducer. Something like this perhaps:

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;
};

Then you can just do this:

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

Of course if you do plan on having more than one SoftwareProducer object, then what you have done seems appropriate.

This seems perfectly reasonable to me.

Check out Factories: encapsulating object creation from Bruce Eckel's Thinking in C++ for more on this particular use of friends.

You might also have a look at the C++ FAQ on friends for some more rules of thumb.

I think making SoftwareProducer as a friend of Software is acceptable but I see no reason why Software has to be the friend of SoftwareProducer class. It is an unnecessary dependency between them. You can take key as a constructor argument for the Software class. Also you might want to make the destructor of Software class private so that nobody except the SoftwareProducer can destroy them.

I won't discuss on the friendship issue, but I tend to dislike cyclic dependencies. Software depends on SoftwareProducer that depends itself on Software... I would try to refactor.

Also note that the friendship relationship opens the internals to all instances of the other class. That is as much as saying that your comment in next_key is false:

Making next_key private disallows any class from calling it, but once you open up to Software class, any software can call next_key on all SoftwareProducers .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM