How to let class have file scope? [duplicate] - c++

So, I know static functions are functions that are local to the file. Thus, they can't be accessed from other files. Does this work for classes too? I've read a ton of controversy on how static class does not declare the class to contain purely static members and methods (which is obvious), but couldn't find anything that mentioned whether or not this would declare the class to be locally accessible to the file scope, as is more logical.
In case it doesn't, what about using an anonymous namespace, which I've heard also can be used to declare file local functions?

You can define a class in unnamed namespace as for example
namespace
{
struct A {};
}
In this case the class name will have internal linkage. That is it is visible only in the compilation unit where it is defined and all compilation units that include that definition will have their own class definitions.
As for the storage class specifier static then (7.1.1 Storage class specifiers)
5 The static specifier can be applied only to names of variables and
functions and to anonymous unions

Does this work for classes too?
No. no such 'static' keyword for class.
As an alternative to an 'anonymous namespace', you can declare a class (Foo) and its definition (implementation) entirely within a single cpp file. The only code which can use this class is the code below that declaration ...
File X.cpp:
// Foo declared
class Foo
{
public:
//...ctor
//...dtor
// etc.
}
// ... Foo defined (implemented)
Foo::etc() { ... }
// implementation of X - only X has access to Foo.
End of X.cpp.
And File X.hpp does not reference Foo.
If you subsequently discover a name collision (i.e. linker reports duplicate symbol), your only choice is to change one or the other name.
There are many Q&A's in SO about anonymous namespaces. I am careful what kinds of things I put into one, and agree they can prevent name collision.
I have used both techniques.

Related

Clarification on classes and scopes in this scenario

I'm currently working with the JUCE Framework to create an audio VST plugin to get to grips and learn, but just want to clarify some basic stuff relating to classes.
in my header file, i have a class EQPLUGProcessor and inside that class i call static juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout();
When i call the function createParameterLayout() in my .cpp i have to write juce::AudioProcessorValueTreeState::ParameterLayout EQPLUGAudioProcessor::createParameterLayout(){}
My question is, why do i have to include the juce::AudioProcessorValueTreeState::ParameterLayout before the actual scope that the function is in ( EQPLUGAudioProcessor)? Surely i should be telling the compiler to look in the EQPLUGAudioProcessor and thats it?
I get that EQPLUGAudioProcessor is the class which its all inside, but still cant seem to understand when, where and why i'd need to clarify the classes that the function comes from again in the .cpp?
Let me know if this requires clarification.
An enclosing namespace or a class does not have to be specified only inside the same namespace or a class:
class store {
class give_me {
// ...
};
static give_me something_cool();
};
Here, the declaration of something_cool() only needs to reference give_me, rather than store::give_me. This is because this declaration appears inside the declaration of its class.
Now that this class is declared, and it's time to define it's class method, everything must be spelled out:
store::give_me store::something_cool()
{
// ...
}
If the class method returned a void instead you'l still have to write something like:
void store::something_cool()
{
// ...
}
You already understand that you can't just write void something_cool() and define this class method. This would only define some unrelated function with this name.
You have to write store::something_cool because this definition no longer appears within the store scope.
Well, the same thing applies not just to class methods but also to inner classes (and also other kinds of symbols that are declared in some enclosing scope). Since give_me is not a class that's declared in global scope, it is an inner class, when in global scope you must reference it as store::give_me.
That's just how C++ works. There are also various complicated rules that define where a scope begins, and ends, with respect to C++'s syntax, that's tangentially related to this. In some cases it is possible to take advantage of these scoping rules and avoding explicit scope references by using an auto declaration with a trailing return type; but how to do that will have to be a different question for some other time.

Why can a static member function only be declared static inside the class definition and not also in its own definition?

While implementing a class for creating/updating boxes on the screen, I wanted to add a static member function that makes sure no currently visible boxes overlap (taking its information from a static pointer array to all currently visible boxes)
My initial code had the following structure:
class Box
{
public:
// ...
static void arrangeOverlappingBoxes();
};
static void Box::arrangeOverlappingBoxes()
{
// ...
}
I was quite surprised that this generated an error C2724: 'static' should not be used on member functions defined at file scope.
With some trial, google and error, I figured out that my function definition should lose the keyword static, i.e. it should be
void Box::arrangeOverlappingBoxes()
{
// ...
}
Yet I have no clue what the rationale behind this could be. It appears to be so asymetric and confusing to have a different function header for its declaration in the class definition and its own definition. Is there any reason for this?
Your class definition (in the header file) will provide the function with whatever propreties are necessary :
static
inlined
virtual
Considering that every further object will look at your class definition using the .h then it makes sense that these properties to be defined there.
Furthermore, each function from the class will mentain it's property in the derived classes (for example you need to declare the destructor virtual only in your base class, every subsequent inheritance will take the destructor as virtual).
It makes no sense to redeclare these properties in your implementation body .
Having to declare function proprieties in both .h and .cpp files would actually lead to allot of problems.
Imagine this scenario : you declare a function as virtual in a .h file, and as static in the .cpp file. What will the compiler make that function ? virtual or static ? (or more likely a compile error , but the compiler error will just urge you to match in your .cpp file the declaration in the header. You cannot overload a function according to "static" or "virtual").

multiple definitions error in c++ and solution to solve this issue

I am new to C++. I have some doubts regarding multiple definitions error in C++.
Let's say I have 3 files in a program. One header file and 2 .cpp files. I have included the header file in both the .cpp files.
I have declared a class in the header file and I have defined the class in each of the .cpp files in exactly the same way. So will this type of implementation cause multiple definitions error? If so, is it because it has two copies of class definitions and the compiler doesn't know which one to take during linkage of two .o files?
Can we solve this problem by using extern in header file and defining the class in only one of the files?If we can solve the issue by using this method,do we have to include the .cpp(with class definition) into other .cpp file(with no class definition)?
I have declared and defined a class in header file. Is this case the same as above (mentioned in 1)?
I have declared a class in the header file and I have defined the class in each of the .cpp files but the definitions (function bodies)differs. So will this type of implementation causes multiple definitions error? If so, how can we solve this problem where the functions bodies differs in the .cpp files?
1) You solve this by 'defining the class' in only one cpp file. Why would you want to define it in two files?
2) Don't define things in header files, only declare them. There are exceptions to this rule, for instance inline functions. Also classes themselves can defined more than once (by this I mean declaring the methods and data members of the class, (i.e. writing class XYZ { ... };) but each definition must be identical. The simplest way to achieve this is to define a class once in a header file. Then each definition resulting from including that header file in multiple places will necessarily be identical.
3) This one is even sillier, it's one thing to define somethiing twice, but define it twice and differently each time makes even less sense.
I guess the issue is why you think it might sometimes be necessary to define things more than once. Don't do that.
You should also make it clear what you mean by 'define the class'. I've taken that to mean define the methods and static members of the class. But if you have something else in mind that might be a source of confusion. As usual the best way to avoid this kind of terminology confusion is to post some code.
To answer all of these questions, you only need to look at the purpose of declarations and definitions.
Declarations of a class simply state that the class exists and in which context. For a class, a simple forward declaration (e.g. class Banana;) allows you to use pointers or references to that class, but that's it.
Definitions state exactly what the class is. That is, which members it has and from what base classes it is derived. You need this available whenever you access members of the class, or need to know the size of its instances. This means the class definition needs to be put in a header file, so that it can be included wherever in all files which use the class. This is OK, because the standard says that a class can be defined in multiple translation units, as long as all definitions are identical.
A class definition typically looks something like this:
class Banana
{
public:
Banana(){}
void eat();
private:
//....
};
However, please note that this class definition only means the definition of the class itself, not the non-inline member functions. Such as void eat() in the above example. These need to be defined in the .cpp file, because they may not be defined in multiple translation units.
So in short:
This is not right, only define it in the header file and define non-inline member functions in the matching .cpp file. You should never define the same function or type in more than one file.
This is OK, as long as you define the member functions separately in the .cpp file.
No, see 1.
1) You can't have two definitions of the same class in your project. And I have no idea how you plan to use it. If you want to make instances of one class with different behavior, use virtual function like:
class A {
public:
virtual int foo() = 0;
}
class B : public A {
public:
virtual int foo() { return 1; }
}
class C : public A {
public:
virtual int foo() { return 2; }
}
2) You may define class in header file (java-style), but it's not the best idea because compiler will consume more resources to build other files, include this header. Let compiler work fast - define classes in .cpp files.
3) See p.1
There's no problem with defining a class in several places. That's exactly what happens when you put the definition in a header and #include that header in more than one source file. However, note that defining a class means writing out what the class contains, not defining its members. This is a class definition:
class C {
void f(); // member function declaration
void g() { } // member function declaration with inline definition
int i; // member declaration
static int j; // member declaration
};
like most things, you can't define it more than once in a single source file. However, it can appear in as many source files as you like, provided only that it's the same everywhere.
This class definition declares two members that must be defined somewhere, typically like this:
void C::f() {
std::cout << "In C::f\n";
}
int C::j = 3;
These definitions can appear only once in the entire program; usually each is defined once in a source file.

Static member vs static global

I have read that the difference between globals and static globals is that the global variable can be referred to in another implementation file via extern, whereas static globals are localized to only that implementation file. See these two questions for more information: [1, 2].
From what I understand, this means the that the following foo() and bar() should be linked identically. Both functions can only be used by MyClass.
//MyClass.h
Class MyClass{
private:
static void foo();
};
//MyClass.cpp
void MyClass::foo(){}
static void bar(){}
I can see foo()'s declaration being more common since it lets the header file lay out the entire class more completely (even if you can't/shouldn't use the private stuff), but is bad practice declare a function like bar() (hidden from the header file)?
For context, I am defining a WNDPROC for windows messages which needs to be static to work, but it's a rather ugly declaration and I'm not sure if I should hide it completely in the implementation file or go ahead and declare it in the header file.
static is a very horrible keyword as it has many different meanings depending on the context. static variables and static functions are completely different, and a static function in a class and a static free-function are completely different.
A static function in a class means that the function can be called without an instance of the class, but it cannot access non-static members of the class. It is a bit like a regular function, just enclosed in the class for tidiness purposes.
A static free-function has internal linkage, so it cannot be seen outside of the source file and its name can be reused in other source files.
A static class function does not have internal linkage. All class functions have external linkage. You can split the class function between header and source files whether the class function is static or not.
I recommend you read some tutorials/books to understand the many different uses of static more clearly. When you see static in a place you've not seen it before, assume nothing!
If you have a free-function which you want hide in a source file, you can declare it static as you have done so. Alternatively you can place it in an unnamed namespace.
// cpp file only
namespace
{
void hiddenfunc() {..}
}
This is similar to
static void hiddenfunc();
And it can be called in the same way (just as "hiddenfunc()"). An advantage of unnamed namespaces (a weird name, I know) is that you can also place classes and other definitions, that you only want to be visible within that source file. Just make sure you define the function body within the namespace {..} area. Don't put an unnamed namespace in a header file.

Anonymous Namespace Class Definition

I was looking over some (C++) code and found something like this:
//Foo.cpp
namespace
{
void SomeHelperFunctionA() {}
void SomeHelperFunctionB() {}
void SomeHelperFunctionC() {}
//etc...
class SomeClass //<---
{
//Impl
};
}
SomeHelperFunction[A-Z] are functions that are only needed in that translation unit, so I understand why they're in an anonymous namespace. Similarly, SomeClass is also only required in that translation unit, but I was under the impression that you could have classes with identical names in different translation units without any sort of naming collisions provided that you didn't have a global class declaration (e.g., in a commonly included header file).
I should also mention that this particular translation unit does not include any headers that might declare a class with an identical name (SomeClass).
So, given this information, could someone please shed some light on why the original programmer might have done this? Perhaps just as a precaution for the future?
I'll be honest, I've never seen classes used in anonymous namespaces before.
Thanks!
An anonymous namespace is like the static keyword when it is applied at the global level.
An anonymous namespace makes it so you can't call anything inside the namespace from another file.
Anonymous namespaces allow you to limit the scope of what's within to the current file only.
The programmer would have done this to avoid naming conflicts. No global names will conflict in this way at linking time.
Example:
File: test.cpp
namespace
{
void A()
{
}
void B()
{
}
void C()
{
}
}
void CallABC()
{
A();
B();
C();
}
File: main.cpp
void CallABC();//You can use ABC from this file but not A, B and C
void A()
{
//Do something different
}
int main(int argc, char** argv)
{
CallABC();
A();//<--- calls the local file's A() not the other file.
return 0;
}
The above will compile fine. But if you tried to write an CallABC() function in your main you would have a linking error.
In this way you can't call A(), B() and C() functions individually, but you can call CallABC() that will call all of them one after the other.
You can forward declare CallABC() inside your main.cpp and call it. But you can't forward declare test.cpp's A(), B() nor C() inside your main.cpp as you will have a linking error.
As for why there is a class inside the namespace. It is to make sure no external files use this class. Something inside the .cpp probably uses that class.
If someone links this code and has the definition of an identical named class included and this file is linked before the other implementation you would have a name conflict.
In the C++ ISO standard (Section 2.3), you will find a rule called The One Definition Rule.
Due to the complex relationship in C++ between compilation and linking, this is not a very simple rule. Most of the details are here.
But it applies to the functions that are members of a class, because they are (at the linking level) simply functions with long names.
It applies in a slightly different way to templates, because the linker will happily discard extra definitions of template classes or functions that appear in separate translation units (source files). This means that if you provide two different definitions of the same template, your program has undefined behaviour (best case scenario: one of the definitions will be silently chosen at random).
I was under the impression that you could have classes with identical names in different translation units without any sort of naming collisions provided that you didn't have a global class declaration
Well, that's not the case. Remember that those "common" global class definitions are in header files. Those are literally included, copying that common global class definition to all translation units. If you use another way of including exactly the same class definitions in multiple translation units (eg. macro expansion), it's fine too. But if you have different definitions for the same class name, you risk undefined behavior. Link failures if you're lucky.
To answer your question directly, I think that this is to avoid linker "multiple definition" errors for static members of SomeClass. That is, suppose SomeClass is defined in a cpp file without an anonymous namespace and there are some static fields and/or static methods in it and these static members are defined next to the class definition in this very cpp-file. Then these static members get the external linkage (are present in the symbol table of the corresponding .o file as GLOBAL).
Now you have another cpp-file and you want to create another SomeClass (unrelated to that one in the first cpp-file and you may be even unaware of the existence of the first SomeClass in that first cpp-file) for your own purposes and again without an anonymous namespace. And you define a static member with the same name as a static member of the first SomeClass. And here you are: you end up with a linkage conflict.
So the author of the first cpp-file should have hidden the first SameClass inside an anounimous namespace, as the class was clearly supposed to be an implementation detail, rather than a class re-used by other people. And so its static members should not have external linkage.
So overall, what I try to say is that non-constexpr/non-inline static members of a class are just like global variables or non-inline functions. And so their linkage can be made internal using an anonymous namespace just like it can be done for global variables and functions using static keyword or again an anonymous namespace.
// .cpp file
namespace
{
struct A
{
static int i;
};
}
int A::i;