Why virtual & static keywords aren't allowed outside class declaration? - c++

I am curious to know why following isn't allowed in C++?
1st program:
#include <iostream>
class Test {
public:
int myfun();
}
virtual int Test::myfun()
{ return 0; }
int main()
{ }
[Error] 'virtual' outside class declaration
2nd program:
#include <iostream>
class Test {
public:
int myfun();
};
static int myfun() {
std::cout<<"This program contains an error\n";
return 0;
}
int main() {
Test::myfun();
return 0;
}
[Error] cannot call member function 'int Test::myfun()' without object
So, my questions are
Why can't I make a member function virtual like as in 1st program?
Why can't I make a member function static like as in 2nd program?
Is there any reason to not allow these 2 keywords outside the class?

The modifiers must be on the function declarations, otherwise it would be impossible to call the functions given just the declarations.
Since they must be on the declarations, it would be redundant to put them on the definitions as well. There's no particularly good reason to disallow them (as long as they match the declaration), but no particularly good reason to allow them either.

virtual has to do with polymorphy and that is why it's only allowed inside a class. static is allowed outside of classes and makes global functions "private". The problem with your program is, is that myfun() in the class Test is not static and you have to create a instance of Test to invoke this method.
int main()
{
Test test;
test.myfun(); // works
return 0;
}
the static version of myfun() has nothing to do with the class and cannot be invoked like that: Test::myfunc() (because, as i said, it has nothing to do with Test). You can invoke it like this:
int main()
{
myfun(); // global function, has nothing to do with any classes
return 0;
}

You want to make a function virtual by stating this outside of class declaration. However, think of other code that will be using your class. You will most probably #include only the header of your Test class, which will contain only the class Test block, not the implementation. So while compiling that code the compiler will not know that a function is virtual. However, it needs to know, because it needs to generate different call code for virtual and non-virtual functions.
In more details, assume a more advanced program than your example. Following to your proposition, it will contain several compilation units and be organized, for example, as follows (#ifdef guards omitted for clarity):
// Test.h
class Test {
public:
int myfun();
};
// Test.cpp
#include "Test.h"
virtual int Test::myfunc() { return 0;}
// other.cpp
int foo(Test& test) { return test.myfunc(); } // <--- *
You will be compiling Test.cpp separately from other.cpp. So when you compile other.cpp, how would the compiler know that it should perform a virtual call to test.myfunc() in foo()?
The same reasoning applies to static functions. However, note that the static keyword has also another meaning that can be used outside of a class declaration.

The compiler compiles one source file ("translation unit") at a time. If you would declare a class
#include "Test.h"
class SpecialTest : public Test {
int myfun();
};
the compiler only sees what is in "Test.h", not what is in "Test.cpp". So if you were allowed to make myfun() virtual in the .cpp file only, the compiler could not correctly compile "SpecialTest" without having to look at "Test.cpp"

As indicated by juanchopanza in the comments, virtual only makes sense in the context ob classes. Recall that a virtual method is a function without an implementation, leaving this to other classes that inherit from the class where the virtual method is defined. But if the virtual definition is outside of a class, how to express inheritance in this case? It would be a non-implemented function without the possibility for other classes to actually implement it.
For static, you are confusing its meaning outside and inside the context of a class. If you want to have a function that can be called without the need for a corresponding object, you can define it as a static function of the class. If you want this function to be outside the class, simply omit the static as the function is available without the need for an object anyway. But static outside of the class context means something completely different.

Related

Is there a Necessity for private static Methods?

The Principle Engineer at my last company had a rule that private static methods should be implemented as functions in the implementation file, not as class methods.
I don't remember if there were any exceptions to his rule. I have stumbled into the motivation for it at my current job: If the arguments or return type of the function in question are objects that would require the inclusion of a definition file in the header, this can cause unnecessary difficulties.
That's enough to steer me away from ever using a private static method again, but before I wrote them off I wanted to know if anyone is aware of a niche they fill that an implementation file function would not?
EDIT:
An example may be helpful here. Say this is the start of the declaration of class Foo, which has other methods which will call void foo() in the implementation file:
class Foo {
static void foo();
So foo is only accessible by other methods of Foo. Why wouldn't I just define foo in the implementation file, and keep it out of the header all together?
Unlike free-standing static functions in the implementation file, private static member functions can be used in the header of the class. This is important in situations when you want to inline a non-private member function, which calls your private static function:
class Demo {
private:
static std::string sanitize(const std::string& name);
std::string name;
public:
Demo(const std::string& n) : name(sanitize(n)) {
}
};
Doing the same with free-standing static functions would require implementing Demo's constructor in the cpp file.
Member functions have access to all private members of the class. If a function needs access to these members, it should be a member. This applies whether or not it's static.
A static function is one that doesn't operate on a specific object. However, it can still receive objects as parameters. For example:
class A
{
int m;
static int process_3_objects_in_some_way(A x, A y, A z)
{
return x.m + y.m + z.m;
}
}
Another reason to make a function static is the order of parameters. For example, print:
class A
{
int m;
static void print(std::ostream& stream, A x, int options)
{
stream << "Value is: " << (x.m * 1000000 + options);
}
}
friend functions or classes which are implemented in another implementation file are another example where a private static member function is required.

Inline member do not need declaration

In C++ we have feature people do not think about much, like we can execute method of a class that uses method/member that has been declared later in class i.e.:
struct s{
foo() { foo1();}
foo1() { assert(0); }
};
int main() {
s s1; s1.foo();
}
I already know that compiler puts member definitions after class definition and it can be found so the order doesn't matter: Do class functions/variables have to be declared before being used?. What I was wondering is how it would look like if we would make methods inline and compiler will respect our request and make them really inline would it work then? Would compiler do any additional stuff to reorder whole class?

Placement of class definition and prototype

When I create a function, I can put the code for it after main if I put the prototype above main. For example,
int myFunction(int a)
{
return(a);
}
would have the prototype..
int myFunction(int a);
above main.
However, I have not been able to get this to work for a class definition.
If I put …
class myClass
{
…
};
below main,
I get an error if I put
class myClass;
above main. The error occurs where the class is used within main, and the error is "unknown type name." That's with the c++ compiler that is part of Xcode.
What kind of prototype should I enter above main if the class definition is below main?
When you call a function and the definition is not available, the compiler doesn't have to know the contents in order to continue evaluating the rest of the code (eg: stack usage at the call site). It only needs to know the function's signature to ensure the correct parameters are going to be passed into the function. The linker will hook up the actual address for the function call after the compiler is done.
However when you are using a class it has to know about the details of it - not just that it exists - because it'll need to ensure proper layout on the stack, what parameters are required for the constructor, etc.
The details of the class' functions are of course like regular functions - it just needs the signature to work with - they can be defined later.
A function in C++ is like a black box to its callers; they just need to know what to pass it and what it returns in order to use it.
Classes, on the other hand, cannot be used in this way, because the compiler needs to know how much space to allocate for them, what the types of their members are, etc.
A class definition is a little different because it can contain member function prototypes and definitions.
If your class definition (usually placed in a .h file) is in the same file, then you'll want it to be above your main(). Functions defined outside of your class definition can be defined after main() as shown below.
class Foo
{
// member function prototype
void func1();
//member function definition inside class
void func2()
{
std::cout << "Hello from func2" << std::endl;
}
};
int main()
{
foo instance;
instance.func1();
instance.func2();
return 1;
}
void Foo::func1()
{
std::cout << "Hello from func1" << std::endl;
}
In a way, a function prototype is the function-equivalent of a complete class definition, not a forward declaration.
so, forward declaration:
class X;
introduces the name X and informs the compiler that it is a class. After seeing this, the compiler will allow you to hold and transfer references and pointers to an X, but not create or copy values (instances) of it, so:
void foo(X&); // is allowed (because it deals in references), but
void foo(X); // is not (it deals in copies of an X)
class definition:
class X { ... };
fully defines X's interface and storage requirements. After this, the compiler will allow you to do anything you like with an X. This is why the class definition generally goes into a header file.
function prototype involving forward-declared classes:
int foo(X&); // X may be forward-declared or defined
This has fully declared the complete shape and behaviour of calling foo(X&). The code at the call-site can be completely compiled.
function prototype involving defined classes:
int foo2(X); // X must be defined
This has fully declared the complete shape and behaviour of calling foo2(X), including the requirements for copying the X onto the stack (for emplacing it there when called with a temporary). The code at the call-site can be completely compiled.

How can I implement a 'main' method in a class in C++?

Consider:
static class EntranceClass {
public:
static void RegisterSomething()
{
}
static int main()
{
RegisterSomething();
return 0;
}
} // <-- Expected unqualified-id at the end
I'm getting the following error:
expected unqualified-id at end of input main.cpp Problem
Is there a solution?
main is just main. It is simply a function:
class EntranceClass
{
...
}; // <-- Note the semicolon
int main()
{
}
The error is referring to the use of the static keyword before the class definition - the compiler expects a variable name after that (as in C++ there is no such thing as a static class).
And if you want to use static int EntranceMain::main(void) as your program's entry point, then one way to do it is to tell that to your linker, i.e., give it a full, decorated name of that function. This is highly dependent on which compiler and linker you use, so you need to refer to their documentation. But using that will probably mean you need to include the startup code (e.g., CRT initialisation).
Note that this is not so standard-compliant, though.
According to the standard, you're not writing a true main function.
Section 3.6.1, paragraph 3: "The function main shall not be used (3.2) within a program. The linkage (3.5) of main is implementation-defined. A program that declares main to be inline or static is ill-formed. The name main is not otherwise reserved. [Example: member function, classes, and enumerations can be called main, as can entities in other namespaces.]"
This means that, by declaring a member function main, you're just declaring a member function. It has no special significance, and doesn't mean anything in the class can be called independently. The program would mean entirely the same thing if you substituted snicklefrazz for that function name and all references.
Stylistically, snicklefrazz would be better, since it wouldn't lead to any possible conclusion with the standard main function.
Section 3.6.1, paragraph 1: "A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function."
This means that, unless you're writing in what the standard calls a freestanding environment (typically used in writing embedded systems), you need to define a main global function, and this is where the program starts.
In Java, a class can have a main method, which is where the program begins when the class is invoked. This is not the case in C++, and there is no way to accomplish this directly.
(And, as others have mentioned, a class cannot be static, and a class definition ends with a semicolon.)
You may have forgotten the semicolon after the closing parenthesis.
You may be looking for the constructor of the object.
Anyway, try to remove static.
This seems like horrible coding style to me to be putting your main into a class, but if you really wanted to do it I think the implementation would be more like so:
class Foo{
public:
int main(){ return 0; };
};
Foo bar;
int Foo::main(){
bar.main();
}
As I said though, this seems to be very bad coding style. You're better off building your class in a .hpp file and then linking it into your program_main.cpp (via #include "foo.hpp") which has the int main(){ return 0; } function for you to call the class.
In C++ you can have "global" functions, i. e. functions that are not members ("methods" in Java lingo) of any class.
By default the entry point to a C++ program is a "global" main() function that in general looks like this:
int main(int argc, char *argv[])
{
// Do stuff
}
The arguments to main() allow your program to take command line arguments. They can be omitted like so
int main()
{
// Do stuff
}
in which case your program does not take any arguments. When a program exits normally, the convention is for main() to return 0. A return value other than 0 is typically used to indicate an error.
There is no notion of a static class in C++. You can have static member functions and data members, or static global variables (different meaning of static inherited from C).
You need a semicolon after the class definition.
One trick you can do is to create a class that is called something like "BaseApp" that is derived from, and then implement a virtual function that calls through to the real version.
class BaseApp
{
public:
virtual void EntryPoint() = 0;
static BaseApp* GetApp() { return this; }
};
Then just derive a class from it, implement an EntryPoint(), and define your object.
class SpecializedApp: public BaseApp
{
public:
void EntryPoint() { ... }
};
SpecializedApp g_App;
Then, you have main() that calls through to it:
void main()
{
BaseApp::GetApp()->EntryPoint();
}
This is a way that you can have main be a type of generic startup routine that can call into different entry points depending on how things are linked in. You could have a Win32 class or a standard C class on top of BaseApp.

How do you create a static class in C++?

How do you create a static class in C++? I should be able to do something like:
cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
Assuming I created the BitParser class. What would the BitParser class definition look like?
If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example, then you won't be able to without using Managed C++.
But the looks of your sample, you just need to create a public static method on your BitParser object. Like so:
BitParser.h
class BitParser
{
public:
static bool getBitAt(int buffer, int bitIndex);
// ...lots of great stuff
private:
// Disallow creating an instance of this object
BitParser() {}
};
BitParser.cpp
bool BitParser::getBitAt(int buffer, int bitIndex)
{
bool isBitSet = false;
// .. determine if bit is set
return isBitSet;
}
You can use this code to call the method in the same way as your example code.
Consider Matt Price's solution.
In C++, a "static class" has no meaning. The nearest thing is a class with only static methods and members.
Using static methods will only limit you.
What you want is, expressed in C++ semantics, to put your function (for it is a function) in a namespace.
Edit 2011-11-11
There is no "static class" in C++. The nearest concept would be a class with only static methods. For example:
// header
class MyClass
{
public :
static void myMethod() ;
} ;
// source
void MyClass::myMethod()
{
// etc.
}
But you must remember that "static classes" are hacks in the Java-like kind of languages (e.g. C#) that are unable to have non-member functions, so they have instead to move them inside classes as static methods.
In C++, what you really want is a non-member function that you'll declare in a namespace:
// header
namespace MyNamespace
{
void myMethod() ;
}
// source
namespace MyNamespace
{
void myMethod()
{
// etc.
}
}
Why is that?
In C++, the namespace is more powerful than classes for the "Java static method" pattern, because:
static methods have access to the classes private symbols
private static methods are still visible (if inaccessible) to everyone, which breaches somewhat the encapsulation
static methods cannot be forward-declared
static methods cannot be overloaded by the class user without modifying the library header
there is nothing that can be done by a static method that can't be done better than a (possibly friend) non-member function in the same namespace
namespaces have their own semantics (they can be combined, they can be anonymous, etc.)
etc.
Conclusion: Do not copy/paste that Java/C#'s pattern in C++. In Java/C#, the pattern is mandatory. But in C++, it is bad style.
Edit 2010-06-10
There was an argument in favor to the static method because sometimes, one needs to use a static private member variable.
I disagree somewhat, as show below:
The "Static private member" solution
// HPP
class Foo
{
public :
void barA() ;
private :
void barB() ;
static std::string myGlobal ;
} ;
First, myGlobal is called myGlobal because it is still a global private variable. A look at the CPP source will clarify that:
// CPP
std::string Foo::myGlobal ; // You MUST declare it in a CPP
void Foo::barA()
{
// I can access Foo::myGlobal
}
void Foo::barB()
{
// I can access Foo::myGlobal, too
}
void barC()
{
// I CAN'T access Foo::myGlobal !!!
}
At first sight, the fact the free function barC can't access Foo::myGlobal seems a good thing from an encapsulation viewpoint... It's cool because someone looking at the HPP won't be able (unless resorting to sabotage) to access Foo::myGlobal.
But if you look at it closely, you'll find that it is a colossal mistake: Not only your private variable must still be declared in the HPP (and so, visible to all the world, despite being private), but you must declare in the same HPP all (as in ALL) functions that will be authorized to access it !!!
So using a private static member is like walking outside in the nude with the list of your lovers tattooed on your skin : No one is authorized to touch, but everyone is able to peek at. And the bonus: Everyone can have the names of those authorized to play with your privies.
private indeed...
:-D
The "Anonymous namespaces" solution
Anonymous namespaces will have the advantage of making things private really private.
First, the HPP header
// HPP
namespace Foo
{
void barA() ;
}
Just to be sure you remarked: There is no useless declaration of barB nor myGlobal. Which means that no one reading the header knows what's hidden behind barA.
Then, the CPP:
// CPP
namespace Foo
{
namespace
{
std::string myGlobal ;
void Foo::barB()
{
// I can access Foo::myGlobal
}
}
void barA()
{
// I can access myGlobal, too
}
}
void barC()
{
// I STILL CAN'T access myGlobal !!!
}
As you can see, like the so-called "static class" declaration, fooA and fooB are still able to access myGlobal. But no one else can. And no one else outside this CPP knows fooB and myGlobal even exist!
Unlike the "static class" walking on the nude with her address book tattooed on her skin the "anonymous" namespace is fully clothed, which seems quite better encapsulated AFAIK.
Does it really matter?
Unless the users of your code are saboteurs (I'll let you, as an exercise, find how one can access to the private part of a public class using a dirty behaviour-undefined hack...), what's private is private, even if it is visible in the private section of a class declared in a header.
Still, if you need to add another "private function" with access to the private member, you still must declare it to all the world by modifying the header, which is a paradox as far as I am concerned: If I change the implementation of my code (the CPP part), then the interface (the HPP part) should NOT change. Quoting Leonidas : "This is ENCAPSULATION!"
Edit 2014-09-20
When are classes static methods are actually better than namespaces with non-member functions?
When you need to group together functions and feed that group to a template:
namespace alpha
{
void foo() ;
void bar() ;
}
struct Beta
{
static void foo() ;
static void bar() ;
};
template <typename T>
struct Gamma
{
void foobar()
{
T::foo() ;
T::bar() ;
}
};
Gamma<alpha> ga ; // compilation error
Gamma<Beta> gb ; // ok
gb.foobar() ; // ok !!!
Because, if a class can be a template parameter, a namespaces cannot.
You can also create a free function in a namespace:
In BitParser.h
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex);
}
In BitParser.cpp
namespace BitParser
{
bool getBitAt(int buffer, int bitIndex)
{
//get the bit :)
}
}
In general this would be the preferred way to write the code. When there's no need for an object don't use a class.
If you're looking for a way of applying the "static" keyword to a class, like you can in C# for example
static classes are just the compiler hand-holding you and stopping you from writing any instance methods/variables.
If you just write a normal class without any instance methods/variables, it's the same thing, and this is what you'd do in C++
Can I write something like static class?
No, according to the C++11 N3337 standard draft Annex C 7.1.1:
Change: In C ++, the static or extern specifiers can only be applied to names of objects or functions.
Using these specifiers with type declarations is illegal in C ++. In C, these specifiers are ignored when used
on type declarations. Example:
static struct S { // valid C, invalid in C++
int i;
};
Rationale: Storage class specifiers don’t have any meaning when associated with a type. In C ++, class
members can be declared with the static storage class specifier. Allowing storage class specifiers on type
declarations could render the code confusing for users.
And like struct, class is also a type declaration.
The same can be deduced by walking the syntax tree in Annex A.
It is interesting to note that static struct was legal in C, but had no effect: Why and when to use static structures in C programming?
In C++ you want to create a static function of a class (not a static class).
class BitParser {
public:
...
static ... getBitAt(...) {
}
};
You should then be able to call the function using BitParser::getBitAt() without instantiating an object which I presume is the desired result.
As it has been noted here, a better way of achieving this in C++ might be using namespaces. But since no one has mentioned the final keyword here, I'm posting what a direct equivalent of static class from C# would look like in C++11 or later:
class BitParser final
{
public:
BitParser() = delete;
static bool GetBitAt(int buffer, int pos);
};
bool BitParser::GetBitAt(int buffer, int pos)
{
// your code
}
You 'can' have a static class in C++, as mentioned before, a static class is one that does not have any objects of it instantiated it. In C++, this can be obtained by declaring the constructor/destructor as private. End result is the same.
In Managed C++, static class syntax is:-
public ref class BitParser abstract sealed
{
public:
static bool GetBitAt(...)
{
...
}
}
... better late than never...
Unlike other managed programming language, "static class" has NO meaning in C++. You can make use of static member function.
This is similar to C#'s way of doing it in C++
In C# file.cs you can have private var inside a public function.
When in another file you can use it by calling the namespace with the function as in:
MyNamespace.Function(blah);
Here's how to imp the same in C++:
SharedModule.h
class TheDataToBeHidden
{
public:
static int _var1;
static int _var2;
};
namespace SharedData
{
void SetError(const char *Message, const char *Title);
void DisplayError(void);
}
SharedModule.cpp
//Init the data (Link error if not done)
int TheDataToBeHidden::_var1 = 0;
int TheDataToBeHidden::_var2 = 0;
//Implement the namespace
namespace SharedData
{
void SetError(const char *Message, const char *Title)
{
//blah using TheDataToBeHidden::_var1, etc
}
void DisplayError(void)
{
//blah
}
}
OtherFile.h
#include "SharedModule.h"
OtherFile.cpp
//Call the functions using the hidden variables
SharedData::SetError("Hello", "World");
SharedData::DisplayError();
One (of the many) alternative, but the most (in my opinion) elegant (in comparison to using namespaces and private constructors to emulate the static behavior), way to achieve the "class that cannot be instantiated" behavior in C++ would be to declare a dummy pure virtual function with the private access modifier.
class Foo {
public:
static int someMethod(int someArg);
private:
virtual void __dummy() = 0;
};
If you are using C++11, you could go the extra mile to ensure that the class is not inherited (to purely emulate the behavior of a static class) by using the final specifier in the class declaration to restrict the other classes from inheriting it.
// C++11 ONLY
class Foo final {
public:
static int someMethod(int someArg);
private:
virtual void __dummy() = 0;
};
As silly and illogical as it may sound, C++11 allows the declaration of a "pure virtual function that cannot be overridden", which you can use alongside declaring the class final to purely and fully implement the static behavior as this results in the resultant class to not be inheritable and the dummy function to not be overridden in any way.
// C++11 ONLY
class Foo final {
public:
static int someMethod(int someArg);
private:
// Other private declarations
virtual void __dummy() = 0 final;
}; // Foo now exhibits all the properties of a static class
There is no such thing as a static class in C++. The closest approximation is a class that only contains static data members and static methods.
Static data members in a class are shared by all the class objects as there is only one copy of them in memory, regardless of the number of objects of the class.
A static method of a class can access all other static members ,static methods and methods outside the class
One case where namespaces may not be so useful for achieving "static classes" is when using these classes to achieve composition over inheritance. Namespaces cannot be friends of classes and so cannot access private members of a class.
class Class {
public:
void foo() { Static::bar(*this); }
private:
int member{0};
friend class Static;
};
class Static {
public:
template <typename T>
static void bar(T& t) {
t.member = 1;
}
};
class A final {
~A() = delete;
static bool your_func();
}
final means that a class cannot be inherited from.
delete for a destructor means that you can not create an instance of such a class.
This pattern is also know as an "util" class.
As many say the concept of static class doesn't exist in C++.
A canonical namespace that contains static functions preferred as a solution in this case.