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.
Related
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.
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.
I have a class:
class M {
public:
static std::string t[];
};
with an initialization that comes later. I want to use the M::t later in a different class (header file):
class Use {
public:
void f() { std::cout << M::t[0] << std::endl; }
};
Is there any way to achieve this without including the whole class M for the header file of the Use? I understand that forward declarations do not allow accessing class members, however this beauty is a static one, so it shouldn't be a huge problem for the compiler..
No, you can't. You can either include the header in the header, or separate the implementation Use::f in an implementation file and include M's header there.
There are no partial classes like in C#, where you can define a class in several files.
Since you are making it a public static member, why don't you create a namespace and embed it there?
namespace myns{
std::string t[];
}
You can access it from anywhere then, just like you would have done with a public static class member.
Forward declarations only allow you to use forward-declared-class pointers or references, not members! If you want to use class members like in your example you have to include the class header, even if it's static.
Here is the solution if you don't want to include M.h in your Use.h header:
Use.h
class Use {
public:
void f();
};
Use.cpp
#include "M.h"
#include "Use.h"
void Use::f() {
std::cout << M::t[0] << std::endl;
}
Also, you have to know it's a bad habit to write code in header files, except of course for inline and templates.
I am learning C++, and I'm trying to learn more about using the friend keyboard.
However, I am having trouble using nested classes in my Header file.
I know that header files should only be used for declarations but I didnt want to include a cpp file with it so I just used a header file to declare and build.
Anways, I have a main.cpp file that I want strictly to be used for creating objects of classes and accessing its functions.
However, I dont know exactly how to create the FriendFunctionTest function in my header file to where I can access it in my main.cpp source file using the header Class object because I'm trying to understand the "friend" keyword.
Here is my header code:
#ifndef FRIENDKEYWORD_H_
#define FRIENDKEYWORD_H_
using namespace std;
class FriendKeyword
{
public:
FriendKeyword()
{//default constructor setting private variable to 0
friendVar = 0;
}
private:
int friendVar;
//keyword "friend" will allow function to access private members
//of FriendKeyword class
//Also using & in front of object to "reference" the object, if
//using the object itself, a copy of the object will be created
//instead of a "reference" to the object, i.e. the object itself
friend void FriendFunctionTest(FriendKeyword &friendObj);
};
void FriendFunctionTest(FriendKeyword &friendObj)
{//accessing the private member in the FriendKeyword class
friendObj.friendVar = 17;
cout << friendObj.friendVar << endl;
}
#endif /* FRIENDKEYWORD_H_ */
In my main.cpp file, I wanted to do something like this:
FriendKeyword keyObj1;
FriendKeyword keyObj2;
keyObj1.FriendFunctionTest(keyObj2);
But obviously its not going to work since the main.cpp cant find the FriendFunctionTest function in the header file.
How do I fix this issue?
And I apologize again, I'm just trying to learn C++ online.
The friend keyword is only used to specify if a function or other class can have access to the private members of that class. You have no need for class inheritance or nesting because FriendFunctionTest is a global function. Global functions do not require any class prefixes when invoked.
Source for friend: http://msdn.microsoft.com/en-us/library/465sdshe(v=vs.80).aspx
You're really talking about several completely different things here. Here are examples for two of them:
1) "Friends":
http://www.learncpp.com/cpp-tutorial/813-friend-functions-and-classes/
// Class declaration
class Accumulator {
private:
int m_nValue;
public:
Accumulator() { m_nValue = 0; }
void Add(int nValue) { m_nValue += nValue; }
// Make the Reset() function a friend of this class
friend void Reset(Accumulator &cAccumulator);
};
// Reset() is now a friend of the Accumulator class
void Reset(Accumulator &cAccumulator)
{
// And can access the private data of Accumulator objects
cAccumulator.m_nValue = 0;
}
2) "Nested classes":
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr061.htm
A friend is not a member. Here is a good example of how "friend" is used in practice.
namespace Bar {
class Foo {
public:
// whatever...
friend void swap(Foo &left, Foo &right); // Declare that the non-member function
// swap has access to private section.
private:
Obj1 o1;
Obj2 o2;
};
void swap(Foo &left, Foo &right) {
std::swap(left.o1, right.o1);
std::swap(left.o2, right.o2);
}
} // end namespace Bar
We have declared a function for swapping Foo's that is more efficient than std::swap would be, assuming that classes Obj1 and Obj2 have efficient move-semantics. (Darn it, you are quick with that green check mark! :))
It is useful to know that because the swap routine is parameterized by a Foo object (two in this case) and is declared in the same namespace as Foo, it becomes part of Foo's public interface, even though it is not a member. The mechanism is called "argument-dependent lookup" (ADL).
I'm asking this in the context of generating wrapper bindings for C++ libraries. Sample code:
union Union
{
protected:
struct ProtClass
{
};
};
Wrapper bindings are written with extern "C" functions, which require types to be accessible (IOW a nested type declaration must be public). A simple workaround for accessing protected declarations in classes is to inherit from the class and use the public redeclaration feature of C++ which enables using the declarations in extern "C" functions. For example:
class Class
{
protected:
struct NestClass
{
};
};
class PubDeclClass : Class // autogenerated
{
public:
Class::NestClass; // redeclare nested class as public (can also use 'using' here)
};
// autogenerated (normally generated only if NestClass isn't a POD type)
void* getNewNestClass() { return new PubDeclClass::NestClass; }
Simple enough, but this trick can't be used with unions since they can't be inherited from.
Do you know of any trick I could use to be able to access a union's nested protected declarations from an extern "C" function?
The purpose of allowing this is to create a 1-to-1 mirror of a C++ library in the target language, meaning that the target language would have the same access specifiers as in the library. The "C" functions are the glue between the C++ code and the target language code (SWIG uses this method as well, although it doesn't always wrap nested declarations).
Personally, I'd love to have some sort of g++ extension that I could use to redeclare a non-public symbol as public with some special syntax, for the sole purpose of writing library wrappers. This would simplify my codegenerator immensely.
Why can't you use a simple wrapper:
struct UnionWrapper
{
union
{
protected:
struct ProtClass { };
};
};
class Z12 : public UnionWrapper
{
};
This is just a work around the phohibition.