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?
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.
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.
You cannot.
Make it a static function in a class and tell people not to modify that class?
This can be simulated by making it a struct instance:
struct foo_t {
void operator()(int, int);
} foo;
// error: redefinition of 'foo' as different kind of symbol
void foo(double, double);
or a function reference:
void foo_impl(int, int);
auto const& foo = foo_impl;
// error: redefinition of 'foo' as different kind of symbol
void foo(double, double);
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.
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.
Related
Can we use , operator to declare multiple functions once ?
This code compiles on gcc:
void f(), g();
void f() {}
void g() {}
int main() {
f();
}
Is it standard or a particularity of the compiler ?
It's standard. Look at all the things you can declare:
int a, *pa, f(int), *g(int);
This is a single declaration, with a single type specifier int and four declarators. Note that the two variable declarations there have different types, despite having the same type specifier. Same deal with the two function declarations. The type specifier only covers the innermost nugget of the type; the individual declarators wrap it in things like pointers or function-ness.
The function definition int f() { ... } is unique and unusual. While it serves to both declare and define a function, and involves some of the same syntactic constructs as declarations, it is syntactically separate from a declaration. Since a declaration is the thing that gets to have a list of declarators, the function definition syntax doesn't inherit that behavior. So you can declare multiple functions in a single declaration, but a function definition is not a declaration (despite the fact that it declares a function!) so you can only do one at a time.
Editorializing a little: This facet of the syntax, with type information spread between the type specifier and the declarator, is one of the core awfulnesses of C and C++. It dates back to the earliest days of C, when the focus of the language meant that most variables were ints and the type was actually the most optional part of a declaration. Most of us have experienced this in the form of int* a, b only making one pointer, but things like the parentheses that crop up when declaring function pointers, and the overall spiral-ness of complex type definitions, also spring from that essential, never-corrected mistake from the early 1970s.
What is the difference between the two declarations in case of foo's arguments? The syntax in the second one is familiar to me and declares a pointer to function. Are both declarations fully equivalent?
void foo(int(int));
void foo(int(*)(int));
They are equivalent as long as int(int) and int(*)(int) are used in function parameter lists. In function parameter list the int(int) is automatically adjusted by the language to mean int(*)(int).
It is the same adjustment mechanism that makes int [] parameter declaration equivalent to int * parameter declaration.
Outside of this specific context int(int) and int(*)(int) mean two different things.
So I have this code:
class xx
{
int getnum(); //Is this a forward declaration or a prototype declaration and why?
};
int xx::getnum()
{
return 1+3;
}
So the question has already been commented in the code but:
Is int getnum(); a forward declaration or a prototype declaration and why?
Neither the term "forward declaration" nor "prototype declaration" are defined in the C++ standard, so very strictly speaking, it's neither. It is simply a declaration. If you want to be more specific, you could call it a non-defining declaration, or "a declaration which is not a definition."
When the words "forward declaration" are used in the standard, they are used to refer to declarations which declare, but do not define, the thing (function or class) they declare. Following this usage, int getnum() is therefore a forward declaration.
"Prototype declaration" of a function is used even less in the standard(1), and mostly when talking about [in]compatibility with C. However, when used, it refers to the exact same concept as a forward declaration of that function. Going by this, you could also call int getnum(); a prototype declaration.
To summarise, the terms "forward declaration" and "prototype declaration" have no formal definition, but from the way they are normally used and understood, int getnum(); can be described as either.
(1) However, a similar term "function prototype scope" is defined in the standard (C++17 N4659 [basic.scope.proto] 6.3.4/1). It establishes the scope of function parameter names in a non-defining function declaration, and it's the closest enclosing function declarator.
C++ only allows full prototype declarations of functions, unlike C in which something like int getnum(); could be a forward declaration of something like int getnum(int);
C.1.7 Clause 8: declarators [diff.decl]
8.3.5
Change: In C ++ , a function declared with an empty parameter list takes no arguments. In C, an empty
parameter list means that the number and type of the function arguments are unknown.
Example:
int f(); // means int f(void) in C ++, int f( unknown ) in C
Rationale: This is to avoid erroneous function calls (i.e., function calls with the wrong number or type of
arguments).
Effect on original feature: Change to semantics of well-defined feature. This feature was marked as
“obsolescent” in C.
Difficulty of converting: Syntactic transformation. The function declarations using C incomplete declaration style must be completed to become full prototype declarations. A program may need to be updated further if different calls to the same (non-prototype) function have different numbers of arguments or if the
type of corresponding arguments differed.
A forward declaration is a declaration of an identifier (denoting an entity such as a type, a variable, a constant, or a function) for which the programmer has not yet given a complete definition.
On the other hand a prototype refers to a function not an identifier.
Hope the following clear things out for you!
int getnum(); // Function prototype. You have not yet implemented the body of getnum() function, thus its a forward delcaration.
class RandomClass; // Forward declaration of RandomClass. You have not yet implemented this class but you need it for the rest of your code.
class xx{
RandomClass *foo; // Our need of having a member like that, made us make a forward declaration of the class RandomClass, above class xx
void BarFunction(); // Function Prototype!
};
int getnum(){ //This is the simply the body of your prototype above. Has nothing to do with the classes
return 1+3;
}
void BarFUnction(){
cout << "foo-bar\n" ;
}
Forward declaration is a type of declaration where you specify an Identifier for a Variable, Constant, Type or a Function without giving it's implementation. it actually tells the compiler about an entity with some meta data like name, size etc.
On the other hand, by prototype declaration for a Function means the declaration of a Function with a name and type signature without specifying the function body. So it's only for the function concept, not for variables, constants or types. And so forward declaration can be regarded as a superset of prototype declaration.
For the above example, according to definitions, it's both forward declaration and prototype declaration. Hopefully I am not wrong.
Hi I am trying to understand the difference between function overloading and method overloading in c++. After googling I came across this. not sure if this is correct. If wrong pls help in correction.
Method overloading and function overloading are related concepts. The term method overloading is defined as a feature which is found in various programming languages such as C++ and Java. It permits the creation of various functions with the same name. However all these functions differ from each other in terms of the type of input and the type of output of the function.
On the other hand, the term function overloading is used in object-oriented programming. It is defined as a technique in which two or more functions which have the same name are distinguished from one another using different numbers and/or types of parameters.
Source : http://www.blurtit.com/q662319.html
In C++ Method is usually used to refer a member function for class or structure while,
Function is a freestanding non member function.
How does the standard declare a Function and Method?
As per the C++ standard, A function declaration is defined in:
8.3.5 Functions [dcl.fct]
In a declaration T D where D has the form
D1 ( parameter-declaration-clause ) cv-qualifier-seqopt exception-specificationopt
and the type of the contained declarator-id in the declaration T D1 is “derived-declarator-type-listT,” the type of the declarator-id in D is “derived-declarator-type-list function of (parameter-declaration-clause) cv-qualifier-seqopt returning T”; a type of this form is a function type86).
Note that the standard further states in #4:
A cv-qualifier-seq shall only be part of the function type for a nonstatic member function
To Summarize only methods(member functions) can be const or volatile.
Overloading Criteria for Function & Method Overloading:
Thus, overloading a function and overloading a method(member function) have different criteria
Function overloading is possible if and only if:
Different number of arguments.
Different sequence of arguments or
Different arguments
While method(member function) Overloading is possible if and only if:
Different number of arguments.
Different sequence of arguments or
Different arguments or
Different cv-qualifer-seq
Note that Return type is not a criteria for overloading. Because C++ allows implementations to ignore the return value from functions/methods.
Code Examples:
Function Overloading:
void doSomething(int i);
void doSomething(std::string,int x);
Method Overloading:
class Myclass
{
public:
void doSomething(int i);
void doSomething(std::string,int x);
void doSomething(int i) const;
void doSomething(int i) volatile;
};
Above is an example of how doSomething() can be overloaded as a free standing function and as a method/member function.
They are the same thing.
However, some prefer calling methods functions that are part of a class, and functions, free functions.
//function overloading
void foo(int x);
void foo(int x, int y);
//method overloading
class A
{
void foo(int x);
void foo(int x, int y);
};
A method/function is overloaded by modifying the signature but keeping its name. The signature consists of:
name
parameter types
cv-qualifiers
So, to overload, you need only change the parameters or the cv-qualifiers. I.e. if the method is part of a class, you could also overload like so:
class A
{
void foo(int x);
void foo(int x) const;
void foo(int x, int y);
};
The prototype foo(int x) const will be called when operating on an immutable object.
On a general sense, functions return values. Methods simply do actions.
The textbook example you'll see a lot is door.open() and hood.open() (yes, we all hate the awful car -> OO analogies, but it's clear in this case). These are methods. You open the door, and there is no by-product. But, it does come down to how the door must be opened, versus how the hood is opened; they are similar enough to share the action, but differ in the detailed implementation (that'd you'd rightfully wish to hide from the user...doors open out, while hoods open up).
Functions, however, replace the original call to the function with the value returned by the function. If I understand correctly, you might show this by measuring a car.exhaust(30, 0), which returns the weight of the carbon, oxygen, and other gasses emitted in 30 seconds, travelling at 0 mph. However, a car.exhaust(30, 60) function would include details not used with a speed variable of 0, and would change the output accordingly.
There are lots of examples of function overloading, this one simply demonstrates how different parameters can affect the logic and output of the function used.
In C or C++ what is the difference between function declaration and function signature?
I know something of function declaration but function signature is totally new to me. What is the point of having the concept of function signature? What are the two concepts used for actually?
Thanks!
A function declaration is the prototype for a function (or it can come from the function definition if no prototype has been seen by the compiler at that point) - it includes the return type, the name of the function and the types of the parameters (optionally in C).
A function signature is the parts of the function declaration that the compiler uses to perform overload resolution. Since multiple functions might have the same name (ie., they're overloaded), the compiler needs a way to determine which of several possible functions with a particular name a function call should resolve to. The signature is what the compiler considers in that overload resolution. Specifically, the standard defines 'signature' as:
the information about a function that participates in overload resolution: the types of its parameters and, if the function is a class member, the cv-qualifiers (if any) on the function itself and the class in which the member function is declared.
Note that the return type is not part of the function signature. As the standard says in a footnote, "Function signatures do not include return type, because that does not participate in overload resolution".
The standard defines two terms: declaration and definition. A definition is a tentative declaration. However, the C99 and C++03 standards have slightly varying definitions.
From C++0x draft:
Appendix C
8.3.5 Change: In C++, a function declared
with an empty parameter list takes no
arguments. In C, an empty parameter
list means that the number and type of
the function arguments are unknown"
Definitions
1.3.11 signature
the name and the parameter-type-list
(8.3.5) of a function, as well as the
class, concept, concept map, or
namespace of which it is a member. If
a function or function template is a
class member its signature
additionally includes the
cv-qualifiers (if any) and the
ref-qualifier (if any) on the function
or function template itself. The
signature of a constrained member
(9.2) includes its template
requirements. The signature of a
function template additionally
includes its return type, its template
parameter list, and its template
requirements (if any). The signature
of a function template specialization
includes the signature of the template
of which it is a specialization and
its template arguments (whether
explicitly specified or deduced). [
Note: Signatures are used as a basis
for name mangling and linking.—end
note ]
The function signature doesn't include the return type or linkage type of the function.
OK, Wikipedia disagrees with me on the return type being included. However I know that the return type is not used by the compiler when deciding if a function call matches the signature. This previous StackOverflow question appears to agree: Is the return type part of the function signature?
Also please note that top-level const and volatile on argument are not part of the signature, according to the standard. But some compilers get this wrong.
e.g.
void f(const int, const char* const);
has the same signature as
void f(int, const char*);
A function declaration is a prototype. A function signature indicates what is the return type and the parameters used that makes up the signature. Consider this:
int foo(int, int); /* Function Declaration */
/* Implementation of foo
** Function signature
*/
int foo(int a, int b){
}
Now, consider this scenario: a programmer is asked what is the function signature for foo:
It returns a datatype of int
Two parameters are also of datatype of int, named a and b respectively
The function prototype on the other hand is to clue in the C/C++ compiler, on what to expect and if the signature does not match up with the prototype, the compiler will emit an error, along the context of 'function declaration error' or 'prototype mismatch'.