tags:

views:

351

answers:

6

Is it possible to prevent overloading of user defined functions in C++? Suppose I have a function as:

void foo(int , int);

Can I prevent foo from being overloaded, and if so how? If I can, can this be extended to prevent overriding of the methods through inheritance?

+3  A: 

You cannot.

sbi
+9  A: 

In a word: no. You can't prevent an overload of foo being defined with a different signature somewhere else and you also can't prevent virtual functions from being overriden.

In the C++ world you have to give some degree of trust to people writing code that winds up in your program.

Charles Bailey
This might be a very dumb question......i am still learning C++. How did the designer of c++ prevent certain operators from being overloaded?
Well, if you invent the language, you get to make the rules. Is that what you meant?
Charles Bailey
I was wondering, how did they achieve this.
With lots of hard work in the C++ working group? (I don't think I understand what you're driving at.)
Charles Bailey
Bjarne Stroustrup designed what became C++, wrote the first C++ compiler, and stayed active in the development of the language. You make up your own language that becomes wildly popular, and you can decide what gets overloaded. In fact, there is a list of operators in the standard, and a list of what cannot be overloaded, and it's up to the compiler writers to enforce that.
David Thornley
I think it's built into the compiler that attempts to overload operators for primitive types is automatically an error. Built-in operators are not same as overloaded operators (not a function, logical operators have short-circuiting, some operators cannot be overloaded at all etc).
UncleBens
Part of C++'s pecularities are for C compatibility, and the built-in versions of many operators fall into this category as well. E.g. operator+(int, char*).
MSalters
+5  A: 

Section 13.1.1 through 13.1.3 of the standard describe the kinds of functions that can not be overloaded:

Certain function declarations cannot be overloaded:

  • Function declarations that differ only in the return type cannot be overloaded.
  • Member function declarations with the same name and the same parameter types cannot be overloaded if any of them is a static member function declaration (9.4).

Note: as specified in 8.3.5, function declarations that have equivalent parameter declarations declare the same function and therefore cannot be overloaded:

  • Parameter declarations that differ only in the use of equivalent typedef “types” are equivalent. A typedef is not a separate type, but only a synonym for another type (7.1.3).
  • Parameter declarations that differ only in a pointer * versus an array [] are equivalent. That is, the array declaration is adjusted to become a pointer declaration (8.3.5). Only the second and subsequent array dimensions are significant in parameter types (8.3.4).
  • Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type (8.3.5).
  • Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.
  • Two parameter declarations that differ only in their default arguments are equivalent.

Otherwise, the function can be overloaded, and there is no way to prevent that.

greyfade
A: 

The only reasonable way would be to give the function C linkage:

extern "C" void foo(int , int);

This works because with C linkage, names aren't mangled, so you can't do any overloading (which relies on encoding the types of arguments into the symbol name).

Obviously this won't extend to member functions.

Greg Rogers
This does not really prevent others from writing `void foo(int) { }` right next to it though.
Johannes Schaub - litb
You can only have one function with a given name that has C linkage, but this doesn't prevent you from having a `foo` with a different signature that itself has C++ linkage.
Charles Bailey
It doesn't prevent overloading. This compiles: `extern "C" void foo(int, int);void foo(double, int);int main() {}`
greyfade
Good point, I hadn't thought about simply declaring other C++ functions over top of it.
Greg Rogers
+1  A: 

Make it a static function in a class and tell people not to modify that class?

UncleBens
A: 

Do what UncleBens said, and include in the class a constant which is an encrypted checksum of the text in the class, and a function to test it for validity. That way, nobody can change the class. Just a thought (maybe not a very good one).

As I think about it, that's pretty dumb because the class would need its own text. However, as an alternative, it could read its compiled binary code, and have a checksum for that. I'm getting out on a limb here.

Mike Dunlavey
The class' binary code (whatever that, how do you untangle the binary mess an optimizing compiler leaves behind?) would have to include that constant. Talk about recursion.
sbi
@sbi: yeah, but it's a standard trick in the embedded world to checksum the binary, if only to detect memory corruption.
Mike Dunlavey