tags:

views:

412

answers:

7

Hey I usually run into a situation where I will create a class that should only be instantiated by one or a few classes. In this case I would make its constructor private and make it a friend class to the objects that should be able to instantiate it. For example (in C++):

class CFoo
{
    // private ctor because only a select few classes should instantiate
    private:
    CFoo()
    {
        ... Do stuff
    }
}

class CBar
{
    // CBar is one of the few classes that only need to use CFoo
    friend class CFoo;
    CFoo *m_pFoo;

    CBar()
    {
        m_pFoo = new CFoo;
    }
}

So my question is: Is this stupid? Or is there a better way to achieve this? I'm especially interested in a way where it would work with C# considering the language lacks the friend keyword completely. Thanks.

+1  A: 

In C# depending on how the class is used, you could define one class within the scope of the other.

public class CBar
{
    CBar()
    {
        m_pFoo = new CFoo();
    }

    CFoo m_pFoo;

    private class CFoo
    {
        CFoo()
        {
            // Do stuff
        }
    }
}
g .
"should only be instantiated by one or a few classes" This would limit it to exactly one.
Marcin
don't like nested classes...this is also kinda coupling isn't it
badbadboy
I don't like nested classes personally. Just pointing out that it can be done if needed.
g .
A: 

Just because only a few specific classes use CFoo, doesn't mean you should explicitly block others from using it. If this is truly the need, you may want to rethink your design. You definitely don't want to force this high amount of coupling within your code. Care to provide some detail as to why you're doing this, so we may better suggest a good solution?

Marcin
A: 

To help think if it is stupid or not, could you provide more concrete example of what the classes are?

I would though say that using friend without a good reason sounds kind of a bit strange to me...in C# you have such a thing as assembly, so you could use internal constructor instead or private constructor and several static creation methods with different access (protected, public, internal...)

badbadboy
A: 

First off, the friend declaration is in the wrong class. CFoo needs to friend CBar in order to give CBar access to it's private members.

Secondly, yes, generally this should be avoided. Classes should rarely care how/where they are used. If they do then that functionality should probably be broken down differently.

Greg Rogers
Exactly what I'm thinking.
Marcin
+1  A: 

You could look at marking CFoo internal

internal class CFoo
  • that might suit your needs. As @g said, you can nest classes within classes, but this is a bit of a code smell IMHO.
KiwiBastard
+2  A: 

The goal here seems to be that you cannot have a CFoo until you have a working CBar.

You could achieve the same with C# by having a private constructor for CFoo and then making a static method in CFoo that takes a CBar argument and calls said constructor and returns the new CFoo.

This would be something like the System.Drawing.Graphics.FromImage(Image image) method.

The question of why C# doesn't have the friend keyword has been covered elsewhere.

Guge
A: 

Just make the class private. That simply limits the scope to your dll (exe, etc.). There's nothing as cool as the friend declaration in C#, but Marcin is right in that you should rethink such designs. If you really need 'friend' support, you could use reflection to simulate it at runtime.

chilltemp