views:

552

answers:

5

All the member variables and member functions in my class ClassA are static.

If a user is trying (by mistake) to create an object of this class, he receives a warning: "ClassA, local variable never referenced", because all the functions are static, so this object is never referenced. So, I want to prevent the user from trying to create an object of this class.

Would it be enough to create a private default (no variables) constructor? Or do I have to also create private copy constructor and private assignment operator (to prevent using the default constructors)? And if I do have to create them too, maybe it would be better just to create some dummy pure virtual function instead, and this will prevent the user from creating an object?

Thank you

+10  A: 

Creating a private default constructor should be sufficient. Both of the other default constructs (copy constructor and assignment) rely on having an instance to work correctly. If there is no default constructor then there is no way to create an instance, hence no way to actually get to the copy construction part.

It would likely save you a few headaches though to define all 3 as private and not implemented.

JaredPar
Once again, down voted because ...
JaredPar
That should be: declare but don't define (implement) the constructor. That will take care of both external code trying to create an instance (constructor is private) and internal code erroneously creating an object: linker error as constructor is not defined.
David Rodríguez - dribeas
+2  A: 

In order to use a copy constructor you have to have an object to copy, so if you've locked down the default constructor you should be safe.

Mark Ransom
+20  A: 

Instead of using a class with all static methods, you may be better off making the methods free-standing functions in a separate namespace. The call syntax would be the same:

namespace::function() instead of classname::function()

and you don't need to deal with someone trying to instantiate your class.

Ferruccio
Definitely much better than having a class with all static methods.
Naveen
+8  A: 

Like others said, a namespace is what you should use. If you want to stay with your class, create a class that has a private constructor, and derive from it, to make your intention obvious:

class NonConstructible { 
    NonConstructible();
};

class SuperUtils: NonConstructible {
    static void foo();
    // ...
    static std::vector<int> globalIDs;
    // ...
};


Ok, now let's look into the namespace which are the one and only way to do this:

namespace SuperUtils {
    void foo() {
        // ....
    }

    std::vector<int> globalIDs;
};

You can call that using SuperUtils::foo(); in both cases, but the namespace has the advantage that in a scope you can use the namespace declaration and directive to bring certain or all members into the current scope, so that you can reference them without using SuperUtils:::

void superFunction() {
    using namespace SuperUtils;
    foo();
}

While generally that should be avoided, it can be helpful when the method is using exclusively much stuff from SuperUtils, which then can improve the readability of the code.

Johannes Schaub - litb
But now you've made globalIDs effectively public, when previously it was private. If globals must exist, how is it an improvement for them to be accessible from anywhere?
Steve Jessop
To get the best of both, you could put the globals in a class, then have non-member friend functions to access them. Or put the globals and functions in the class, then have inline free functions in a namespace to call them without specifying the class scope.
Steve Jessop
"previously it was private" - sorry, I mean previously it could be private. Questioner didn't say it was.
Steve Jessop
use anonymous namespace to achieve the same effect as private static memebrs of a class. namespace Utils{namespace{int myPrivate=9;} int myPublic(int arg);}
Arkadiy
That places constraints on how you arrange your code into compilation units. To get the effect of private, you must have precisely the member functions of the class, plus any friends, in the compilation unit. No more and no less. 1.3 out of 5 on the bodge-o-meter.
Steve Jessop
@onebyone: You're wrong. You can put a "namespace-anonymous-ed" variable anywhere (not in a header, though). The only constraint is that the functions using them are written after them. No need for friend, or even declaration in a header. "private" is more "public" than "anonymous namespace".
paercebal
Note: I wrote "not in a header not because it is impossible, but because it would be a VERY BAD idea (i.e. you would end up with as much separate anonymous variables with the same "name" as there are compilation units including your header).
paercebal
Yes, all functions using "private" variables in anonymous namespace need to be in one file. If this was not a requirement, I would have to invent it :)
Arkadiy
@paercebal: My complaint is that anon-namespace globals have to be in the same source file as everything which uses them. So if three free functions use them, those three free functions must all be in the same source file. That's not the case with class private members.
Steve Jessop
My further complaint is that anything in the same source file can access them, also not the case with class private members. Although as you correctly point out, it's not quite that simple, since anything before the declaration can't see them. IMO that's a poor way to do access control.
Steve Jessop
Private isn't "more" public than anon-namespace, it's differently public. Anon-namespace is neither a superset not a subset, so cannot be strictly ordered within the private < protected < public sequence
Steve Jessop
@onebyone: About private: A private member is "visible" to everyone including the header. This is not important, because it can't be accessed, but then, you are using a symbol, which must be either forward declared (and thus, declared a a pointer, and thus, newed) or fully defined (i.e. dependancy)
paercebal
Not really an issue in this case, where all members are static and the class is (I assume) not intended to be instantiated. So come to think of it, contrary to what the question states it should declare one non-static member function: a private default constructor ;-)
Steve Jessop
@onebyone: That's exactly what I eventually did. I tried to implement the namespace solution, but since I do have private members, I saw that it is better to leave at as a class.Thanks to everyone for the help!
Igor Oks
A: 

The best way to prevent creation of non-heap objects is to make destructor private. Then there is no way compiler can destruct the object when it goes out of scope and it will complain. This will not prevent anyone from doing new however.

Tomek