Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

like image 678
Alex Avatar asked Apr 18 '09 07:04

Alex


People also ask

Does C# have friend classes?

friend in C#A friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of the class. Even though the prototypes for friend functions appear in the class definition, friends are not member functions.

What is the use of friend function and friend classes in C++?

A friend function is a special function in C++ which in-spite of not being member function of a class has privilege to access private and protected data of a class. A friend function is a non member function or ordinary function of a class, which is declared as a friend using the keyword “friend” inside the class.

Can a friend class be inherited?

In C++, the friendship is not inherited. It means that, if one parent class has some friend functions, then the child class will not get them as friend.

What are the characteristics of a friend class?

Characteristics of a Friend function:It cannot be called using the object as it is not in the scope of that class. It can be invoked like a normal function without using the object. It cannot access the member names directly and has to use an object name and dot membership operator with the member name.


1 Answers

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.

like image 104
Evan Teran Avatar answered Sep 27 '22 19:09

Evan Teran