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.
Related
I have always thought of header files as a sort of 'public interface' describing a class, in which case it would be better to keep private fields and functions in the .cpp file.
I understand that private fields need to be in the header so that other classes can tell how much memory an instance of a class will consume, but it occurred to me as I was about to write a private helper function, that this function could be made static, in which case there was no need for it to be 'part of the class' at all, it could just as easily be a regular function in the class definition's .cpp file.
It then occurred to me that all private functions could potentially be rewritten to be static by accepting pointers/references to class fields instead of expecting to be defined in the class.
This would eliminate the need to declare any private functions in the header file.
I do like to follow conventions, so is it considered an established convention in C++, that non-static private functions should be in the header file? What about static functions or static constants?
I'm going to put in some code to explain what I'm getting at:
.h file:
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass
{
private:
int x;
public:
void combineWithX(int y);
};
#endif
.cpp file
#include "SomeClass.h"
void someHelper(int* x)
{
*x = (*x) + 1;
}
void SomeClass::combineWithX(int y)
{
someHelper(&x);
x += y;
}
Note that someHelper(int* x) in the .cpp file references the private member x in spirit, but not directly, and therefore does not need to appear in the header. I'm wondering if this sort of thing is considered 'bad style'.
Private helper functions can be hidden from the public header file by moving them to an inner class. This works because the inner class is considered part of the class and can access the surrounding class's private members.
Unlike the PIMPL idiom, this does not have any dynamic allocation or indirection penalty. Compile times should be faster when editing/refactoring private functions, as there isn't any need to recompile all the files, including the public header.
Example:
public .h file
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass
{
private:
// Just forward declaring in public header.
struct Private;
int x;
public:
void combineWithX(int y);
};
#endif
in .cpp file
#include "SomeClass.h"
// Declare all private member functions of SomeClass here
struct SomeClass::Private
{
static void someHelper(SomeClass& self)
{
self.x = self.x + 1;
}
};
void SomeClass::combineWithX(int y)
{
Private::someHelper(*this);
x += y;
}
I agree that it is a problem that implementation details need to be exposed in a header file; it interferes with separation of interface and implementation.
Moving private helper functions to be free functions in the .cpp file (I presume that is what you meant by "static") won't work if those functions need to access private member variables.
You may be interested to look at the pImpl idiom (more)
Sometimes I see people using two different headers, a public header and a private one, like this:
// SomeClass.h - - - -
SomeClass
{
public:
// public functions
}
// SomeClass_.h - - - -
SomeClass
{
public:
// public functions
private:
// private functions
}
// SomeClass.cpp - - - -
#include "SomeClass_.h"
// SomeClass implementation
This has the advantage of a public header that isn't cluttered with private function declarations, but it requires the developer to maintain 3 copies of each function signature.
Header files have long been recognized by many as being problematic in general, not only because of the added maintenance overhead associated with them, but also because of the effect they have on the build environment. It's easy to write code or set build settings that cause a cascade of system or external headers to fail to compile, resulting in a large number of potentially obscure errors. C++20 Modules are an alternative that may be worth exploring.
I have a source.C:
#include "image.h"
#ifndef SOURCE_H
#define SOURCE_H
class Source
{
private:
Image* img;
public:
virtual void Execute()=0;
Image* GetOutput();
};
#endif
Image* Source::GetOutput()
{
return this->img;
}
and a sink.C.
#include "image.h"
#ifndef SINK_H
#define SINK_H
class Sink
{
private:
Image* img1;
Image* img2;
public:
void SetInput(Image* input1);
void SetInput2(Image* input2);
};
#endif
void Sink::SetInput(Image* input1)
{
this->img1 = input1;
}
void Sink::SetInput2(Image* input2)
{
this->img2 = input2;
}
I have a filter.h that I want to inherit from Source and Sink:
#include "image.h"
#include <iostream>
#include <stdlib.h>
class Source;
class Sink;
class Filter : Source, Sink
{
public:
Filter() {std::cout << "Constructing filter." << std::endl;}
};
However, the compiler gives me errors of invalid use of incomplete types 'class Source' and 'class Sink'. I also get an error of forward declaration for those same classes. The classes originally had their functions defined directly in public, so I moved them out, but that didn't help with this. Explicitly setting Source and Sink as public didn't help either. What's going on?
#include "sink.h"
#include "source.h"
should sort you out.
Also this line:
class Filter : Source, Sink
This is private inheritance, which is almost always what you don't want (you won't be able to use the class polymorphically).
You may need to change this to
class Filter : public Source, public Sink
It's because in your filter.h you are giving an incomplete declaration:
class Source;
class Sink;
but not defining them. The compiler needs to know the size of both in order to calculate the size of Filter in:
class Filter : Source, Sink
{
public:
Filter() {std::cout << "Constructing filter." << std::endl;}
};
The solution is to include the header files for both. And for that you'll probably need to separate declaration from implementation in header files and source files.
Forward declaration only lets compiler to know that a name exists, but it does not tell anything about the definition of the name. In order to inherit, the base class' definition must be known. You have to include the headers in filter.h so that compiler can see the definition of the parent classes.
Edit
Declaration means a name exists, definition means what the name looks like. For class definition, it means what the class contains, it's members, size etc. When a class is inherited by another, the compiler kind of places the members of base class in the derived class. So it has to know what the base class looks like. By including the header where base class is defined, compiler actually places the definition in the included file, hence it knows about the base class.
As others pointed out about your privately inheritance, I recommend you to read is-a has-a relationship and difference between private and public inheritance
There are two problems here
The first, as mentioned by others is that you need to include the headers for Sink and Source. At the moment you only have a forward declaration, which will let you use a pointer, but not derive from, or instantiate. The compiler doesn't know the size, or what methods it provides, or how to construct.
The second problem, which you will hit once you include the headers, is that the Sink class has a pure virtual function in it. This makes it an abstract base class.
You need to derive from this (which you have) and implement the Execute method in the derived class (which you haven't)
When declaring and implementing a class or struct in c++ we generally do:
H file
namespace Space{
class Something{
void method();
}
}
CPP file
void Space::Something::method(){
//do stuff
}
OR
namespace Space{
void Something::method(){
//do stuff
}
}
Note how it is possible to wrap all the implementations inside the namespace block so we don't need to write Space:: before each member.
Is there a way to wrap class members in some similar way?
Please note I want to keep source and header file separated. That's generally a good practice.
Not without sacrificing the separation between header and implementation (cpp) file.
You can declare everything inline in the header inside the class, but it's very messy for large classes.
What's the problem you're actually trying to solve? Or is it just typing time? :)
Yes:
.h file:
namespace Space{
class Something{
void method()
{
// do stuff
}
};
}
I don't recommend it, though.
You can not if you keep the .cpp file.
Otherwise, you can, but you would essentially just be dropping the .cpp file.
In your .h file, you could have:
namespace Space{
class Something{
void method()
{
//Method Logic
}
};
}
Except, as you know, there would be limitations as to where you could include the header.
I'm not so sure this will help you, the OP, as you seem to know what you're doing, but I'll include it for future users of the question:
What should go into an .h file?
No, unless you put the class members directly into the class definition
class Something
{
void method() {}
};
This is discouraged as it leads to header bloat if your class definition is in a header file.
I prefer not to use the wrapping method myself, so each function body explicitly states its namespace. This helps detect typos or dead code if you remove the prototype.
I was wondering if there is a way to put objects of a class in a header?
For example:
class MyClass {
} object;
If I made an object there and then include the header in more than one source file, I get an error of multiply defined symbols found. I am new so don't understand fully everything.
Also, I want to do something like object.function() inside of a different function which is a member of a different class how can I do that?
Assuming you want a single object, in the header file just declare the object:
extern blabla object;
and then in one source file define it:
blabla object;
As for calling a method on an object from a different class, that is perfectly fine as long as the method is public.
class foo
{
public:
void public_method();
private:
void private_method();
};
void some_other_class::method(foo &f)
{
f.public_method(); // this is fine
f.private_method(); // this is not okay, private_method can only be called from
// within foo
}
There's also a third visibility (protected), which comes into play once you start dealing with inheritance.
You can find ways to do it (see the other answers), but just don't do it. As you said, you are new to C++, so better learn the good practices, and when you need global objects - create them in the source (cpp) file.
Besides it, try to avoid using global objects at all, and define your objects inside the classes or functions.
It's not a good practice to put definitions in header files as this would result to the error you encountered. Although there are ways to get around this (extern, header guard), it should be avoided as much as possible. Just remember, put declarations in header files, definitions in source files.
About your second question note you can also call a static method using the :: operator and the class name (without an instance) :
void AnOtherClass::method()
{
TheFirstClass::static_method();
}
You could also make a use of the singleton pattern, if that fits your need in this case.
For your second question. You can always make a class object as a (private) member variable of the class you want to call object.function() from.
For example:
// File a.h, includeguards etc. left out for clarity
class A {
public:
void func();
};
// File b.h
#include "a.h"
class B {
public:
void func();
private:
A object;
};
// File b.c
#include "b.h"
void B::func()
{
object.func();
}
Hope that helps.
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.