I am working on a project in C::B and need to use global instances of classes, across the multiple project files. (I'm new to usage of header files and global classes)
I have declared, defined, initialized classes and functions thus:
//in complex.h
class Julia
{
public:
double R;
double I;
void algorithm();
};
Julia J;
//in complex.cpp
#include "complex.h"
void Julia::algorithm()
{
//fn body here
}
//in main.cpp
#include"complex.h"
int main()
{
//calls initialize() and display()
}
void initialize()
{
//...some code(irrelevant)
cin>>J.R>>J.I;
}
void display()
{
J.algorithm();
//some more (irrelevant) code
}
On building and running the code, I get the error- "first defined here" and the Build log shows :
obj\Debug\complex.o:complex.cpp:(.bss+0x3bf0): multiple definition of `J'
obj\Debug\main.o:C:/Users/ShA/Documents/etf_build/main.cpp:20: first defined here
[This is for my 12th grade school project, and I don't think I would be allowed to use singletons (restrictions), even though they seem to be suitable. ]
Can somebody point out the possible errors in the code and how to find a solution to the errors I'm getting?
The declaration
Julia J;
in your header is a definition of J, and via inclusion of the header you have this definition in two translation units: the main.cpp translation unit and the complex.cpp translation unit.
The linker doesn't know that they're (were intended to be) the same definition.
As the linker sees it, it's two separate and conflicting definitions of the same thing.
A purely technical solution is to make J a singleton, and a simple way to do to that is via a static variable in a function, which is called a “Meyers' singleton”:
inline
auto J()
-> Julia&
{
static Julia the_object;
return the_object;
}
The technical solution above is ungood because the singleton, like the direct global variable, introduces complex arbitrary lines of communication, e.g. as via your init function.
There is an even more ungood possible technical solution of declaring the variable as extern in the header, and defining it in the corresponding implementation file. That's extra ungood because in the more general case it runs the risk of using the variable uninitialized. That's called the “static initialization order fiasco”, and is discussed in the C++ FAQ.
Instead of these technical workarounds you should change the design and let main create the Julia instance.
It can be passed down to invoked functions.
If you find that it's passed to a number of functions, in particular as a first argument, then maybe these functions should be member functions of the Julia class, or maybe you should then introduce a new class for this.
in complex.h
Julia J;
This is your error. Any source file that #includes complex.h has its own version of J. This violates the one definition rule.
If the only place you are using the global variable J is in your int main, there is no reason to make that variable global. Make J a local variable inside your main function. Declaring a global variable that is used in only one place is just wrong.
On the other hand, if you are using that variable in multiple files, what you are doing is also wrong. In this case, your complex.h header file should qualify your variable J with the extern keyword. Now you can reference that global in multiple places (but beware the static initialization fiasco). You can reference that variable in multiple places. You need to define that variable in exactly one place.
Place a static Julia& GetInstance() function inside your class Julia declaration (in the header file).
Place an instance of the Julia (Julia J) inside the source file. Then inside the GetInstance() implementation (also in the source file), return J.
Complex.h
class Julia
{
public:
double R;
double I;
void algorithm();
static Julia& getInstance();
};
Complex.c
#include "complex.h"
Julia J;
void Julia::algorithm()
{
//fn body here
}
Julia& Julia::getInstance() { return J; }
Related
I was reading about static functions and it was said that if the function is static then you can use it only in the same file. After testing it, I realized it is not true because if you include the file with a static function you can still use that function in another file. Then I read a clarification that you can actually use static function only in the same translation unit. Ok, that makes sense because it means .cpp + includes, but even if the function is not static, you will still not be able to use it unless you include the file. So how is it even possible to access a function from another translation unit in the first place without including anything, what is the point of static functions?
Main.cpp
#include "Staticf.h"
void main()
{
visible();
}
Staticf.h
#pragma once
#include <iostream>
using namespace std;
static void visible()
{
cout << "Static function is visible\n";
}
This compiles alright. If I make that function non-static and remove #include "Staticf.h" I will not be able to use it in Main anyways. So why are static functions needed if you can't access non-static as well?
You can access non-static functions from other translation units. You just need a forward declaration:
somemodule.cpp
void func()
{
// details
}
main.cpp
void func();
int main()
{
func();
}
It is, of course, a best practice to put the forward declaration in a header file.
So what use are static functions?
In modern C++, they actually aren't much use. static is a feature C++ inherited from C. In C, declaring a helper function static is actually pretty useful because C doesn't have namespaces. You can use static to eliminate the chance of name collisions between your private helper functions and the private helper functions in other translation units. In C++, it's generally preferred to wrap your private helpers in a class or anonymous namespace.
If the function is static (as if free static function), you cannot access it from another translation unit.
Remove the static, and if you can't include a header (you probably can though... change the former static function's header), add a prototype in the file.
I would like a function that is not a member of a class and is accessible from any class.
I assume I would have to #include the header file where the function is declared, but I don't know where to define such a global function.
Are there good reasons against having such a function in the first place?
you need a body (in a cpp file):
int foo()
{
return 1;
}
and a definition/prototype in a header file, which will be included before any use of the function:
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
int foo();
#endif
then using it somewhere else:
#include foo.h
void do_some_work()
{
int bar = foo();
}
or use an inline function (doesn't guarantee it'll be inlined, but useful for small functions, like foo):
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
inline int foo()
{
return 1;
}
#endif
alternatively you can abuse the C-style header based functions (so this goes in a header, the static forces it to exist in a single compilation unit only, you should avoid this however):
#ifndef MY_FOO_HEADER_
#define MY_FOO_HEADER_
static int foo()
{
return 1;
}
#endif
What you are calling global function is usually called a free function and they are A Good Thing.
You would define it just like a class' member function, but outside of that class' scope.
double squared(double x) {
return x*x;
}
Simple functions you can define with the inline keyword in the header file, or just declare it there
double squared(double x);
and put the implementation (first example) into the *.cpp file.
In a header file:
// someheader.h
#ifndef MY_GLOBAL_FUN
#define MY_GLOBAL_FUN
void my_global_fun();
#endif
In an implementation file:
#include "someheader.h"
void my_global_fun()
{
// ...
}
In other files that require that function:
#include "someheader.h"
void f()
{
my_global_fun();
}
Free functions like this are useful and there are not many arguments against using them. Depending on your use case, its likely appropriate to put these functions in a specific namespace to avoid name collision with other libraries you may be using.
Think of main(). The function is kind of just...there. It's not within any class, struct or namespace. You just declare and give it a body. Of course, in the case of functions that are not main, it's best to put a prototype in a header and the define it in a .cpp file.
Remember, C did not have classes and structs could not hold member functions. There was nothing wrong with free functions then and there isn't now.
You have to declare its prototype in header file and define it in implementation file.
//file.h
void foo();
//file.cpp
void foo ()
{}
To shortly answer your second question, Global functions are needed when they are used by several different classes and types in a generic way. For example math functions.
Otherwise, in general you may avoid so many global functions. Also you should avoid having a static local member or global data associated with such function (so that you don't have to worry about thread safety).
In addition to the answer by #Necrolis, the use of static is deprecated in favour of unnamed namespaces. However, use of unnamed namespaces and static both creates separate copies for each translation unit which increases the size of binary. The use of inline is better than both of these in this sense.
These solutions allow for more usage specific optimisations by compilers but are less instruction cache friendly compared to definition in a source file and then linking.
Learning C++ and see the class laid out like this:
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area () {return (x*y);}
};
void CRectangle::set_values (int a, int b) {
x = a;
y = b;
}
I know Java and methods(functions) in Java are written within the class. The class looks like a Java interface. I know I can write the class like this:
class CRectangle {
int x, y;
public:
void set_values (int a, int b) {
x = a;
y = b;
};
int area () {return (x*y);}
};
But is there a difference or standard?
There's a difference. When you write the definition of the function within the class definition (case 2), then the function is considered to have been declared inline. This is standard C++.
Usage, is to declare the member functions (Java methods) within the class definition, in a header file (.h), and to define these member functions in a C++ file (.cpp, .cc, or .C, …) This reduces compilation time, when you change the body of a function, only the C++ file has to be compiled, whereas if you change something in the header file, all C++ files that include this header are to be compiled.
It's much cleaner if you only define prototypes in the class definition (which belongs into a header file) and implement the methods in a cpp file.
When you have very small classes doing everything in the class definition might sound easier since everything is at the same place, but as soon as your class grows any developer using it will hate you since he'll have your code between the method prototypes he might look at to find out something (not everyone uses an IDE which shows all available methods!).
However, there is one exception: Template class methods needs to be implemented in the header as they need to be compiled for every specialization of the template.
The usual way is to put the implementation of functions within a separate cpp file, which is not included by other files, just compiled. This way it is easier to manage dependencies.
If the implementation of a function is given within the class definition (as in your 2nd example), this is a hint for the compiler to inline that function (which it may or may not do in the end, depending on e.g. the internals of the function). As a rule of thumb, function bodies longer than a few lines of code are better put into the cpp file, as these are probably not going inlined, however these may include extra dependencies and clutter the class definition.
The exception is template functions, where the bodies need to be in the header too, for the compiler must see them in order to instantiate the template.
I believe that if the method body is inside the class definition, then it is inlined everywhere is it called.
In C++, member functions which are defined in class are implicitly inline, member functions defined outside the class are not.
This affects the linkage of your two examples - the linker will complain about multiple definitions if the first example is #included in multiple source files, whereas the second example will not.
In terms of what's standard/normal:
The first form is used for complex classes, where the implementation of the functions requires extra headers to be pulled in.
The second form is used for simple classes which don't have extra dependencies.
Either form is used for template classes based on developer preference.
There is a slight difference in that functions defined inside the class are automatically inline. The latter definition can be put into a separate file. Otherwise there is no difference nor preference.
Note that we usually don't write semicolons after function definitions (though they are allowed inside a class definition).
void set_values (int a, int b) {
x = a;
y = b;
} // no semicolon here
I have a few questions about the static keyword in C++ (and probably with other languages as well.) What is the purpose of declaring a function as static?
void static foo(int aNumber) {
... }
How about a static inline function?
void static inline foo(int aNumber) {
... }
Is there any benefit to using the static keyword with a function, and do those benefits apply to class functions as well?
I realize some datatypes like structs and arrays have to be static when compiling with an older compiler, but is there any point when using a new ANSI-C++ compiler (like MS VC++ 2008)? I know that using a static variable inside a loop saves time by keeping the data in memory and not reallocating memory every loop iteration, but how about when a variable is declared only once, like at the top of a header file or within a namespace?
Depends on Context:
Like many things in C++, static means different things depending on its context.
It's very common in C++ for the same word to mean different things depending on its context.
For example:
* is used for multiplication, dereferencing a pointer, and creating pointers.
& is used to get the address of variables, to declare a reference, and as a bitwise AND operator.
Global use of static:
If you declare a function or variable as static outside of a class and in global scope, it is specific to only that file. If you try to use that variable or function in a different file (via a forward declaration) you will get a linking error.
Example:
a.cpp:
static void fn()
{
cout<<"hello a!"<<endl;
}
b.cpp:
void fn();
void gn()
{
fn();//causes linking error
}
This feature allows you to use a function that no other file will ever see, that way you don't cause possible linker errors of a symbol defined multiple times. The preferred method to do this is with anonymous namespaces though:
a.cpp:
namespace
{
void fn() // will be static to a.cpp
{
cout<<"hello a!"<<endl;
}
}
Inside of a class use of static:
If you declare a function or variable as static inside of a class (or struct), it is a class function or class variable. This means that there is only one for that whole class. A class function can only use class variables. A class variable is shared amongst all instances of that class.
class C
{
public:
static void fn()
{
y = 4;//<--- compiling error
// can't access member variable within a static function.
}
int y;
}
This is a great feature to use if you have something that is specific to the class of your objects, but not specific to an instance.
Inside a function use of static:
If you declare a variable as static inside of a function, you can consider that the variable value will persist upon calls. It will only be initialized once.
Example:
//Will print 0, then 1, then 2, ...
void persistentPrintX()
{
static int x = 0;
cout << x << endl;
x++;
}
I personally try to avoid this, and you probably should to. It is not good to have global state. It is better to have functions that given the same input guarantees the same output.
Just like in the English language:
The concept of context sensitive meaning is not specific to C++, you can even see it in the English language.
I am going to screen a movie (Means showing the movie)
The screen on the TV is broken (Means a part of the TV)
Other meanings in other programming languages:
Depending on the programming language there can be a different meaning, but the first thing most people think of when you say static is a class variable/function vs a member variable/function.
I hang around on the ##c++ irc channel on irc.freenode.net and I really like the clarification on static that the bot nolyc is programmed to give. I quote word for word:
When used inside a function, the
static keyword indicates that a
variable is shared between all calls
of the function. When used inside a
class, it indicates that the variable
or function is a member but is not
tied to a specific instance. When
used inside a namespace, it specifies
internal linkage.
I hope that clears things up. I haven't answered all your questions. I would say that you should use the static keyword to do what it was intended to do. Use it as a tool to accompolish your task, if it is the right one for the job. As far as benefits go, I wouldn't worry. If you need to optimize, then think about those effects if there is no other resort.
I hope this helps.
If I have a class in outside.h like:
class Outside
{
public:
Outside(int count);
GetCount();
}
How can I use it in framework.cpp using the extern keyword, where I need to instantiate the class and call GetCount?
Edit:
#include is not allowed.
Everyone here is a bit too gentle.
There is ABSOLUTELY NO REASON why you would not want to include the .h file.
Go for it and include the file!
Just to clarify. It is impossible to extern the class:
class Outside
{
public:
Outside(int count);
GetCount();
}
But, once you have the class available in framework.cpp, you CAN extern an object of type Outside. You'll need a .cpp file declaring that variable:
#include "outside.h"
Outside outside(5);
And then you can refer to that object in another file via extern (as long as you link in the correct object file when you compile your project):
#include "outside.h"
extern Outside outside;
int current_count = outside.GetCount();
extern is used to say "I KNOW a variable of this type with this name will exist when this program runs, and I want to use it." It works with variables/objects, not classes, structs, unions, typedefs, etc. It's not much different from static objects.
You may be thinking about forward declaring classes to cut down on compile times, but there are restrictions on that (you only get to use the objects as opaque pointers and are not able to call methods on them).
You may also mean to hide the implementation of Outside from users. In order to do that, you're going to want to read up on the PIMPL pattern.
Update
One possibility would be to add a free function to Outside.h (I've also added a namespace):
namespace X {
class Outside {
int count_;
public:
Outside(int count) : count_(count) { }
int GetCount()
{
return count_;
}
};
int GetOutsideCount(Outside* o);
}
Implement that function in a .cpp file. While you're at it, you might as well make the global variable that you intend to extern (note, the variable itself does not need to be a pointer):
#include "outside.h"
namespace X {
int GetOutsideCount(Outside* o)
{
return o->GetCount();
}
}
X::Outside outside(5);
And then do this in your program (note that you cannot call any methods on outside because you did not include outside.h and you don't want to violate the one definition rule by adding a new definition of the class or those methods; but since the definitions are unavailable you'll need to pass pointers to outside around and not outside itself):
namespace X {
class Outside;
int GetOutsideCount(Outside* o);
}
extern X::Outside outside;
int main()
{
int current_count = GetOutsideCount(&outside);
}
I consider this an abomination, to put it mildly. Your program will find the GetOutsideCount function, call it by passing it an Outside*. Outside::GetCount is actually compiled to a normal function that takes a secret Outside object (inside Outside::GetCount that object is referred to via the this pointer), so GetOutsideCount will find that function, and tell it to dereference the Outside* that was passed to GetOutsideCount. I think that's called "going the long way 'round."
But it is what it is.
If you aren't married to using the extern keyword, you can instead go full "let's use C++ like it's C" mode by adding the following two functions in the same way (i.e., via forward declarations and implementing right next to int GetOUtsideCount():
Outside* CreateOutsidePointer(int count)
{
return new Outside(count);
}
void DestroyOutsidePointer(Outside* o)
{
return delete o;
}
I'm more willing to swallow that. It's a lot like the strategy used by the APR.
You don't make classes extern. Just include "outside.h" and create an instance of Outside.
you cant extern the class, but you can extern a function that creates an instance.. In the consumer code:
class Outside;
extern Outside* MakeAnOutside(int count);
extern int GetOutsideCount(Outside* outside);
Then in outside.h:
Outside* MakeAnOutside(int count)
{
return new Outside(count);
}
int GetOutsideCount(Outside* outside)
{
return outside->GetCount();
}
but.. this may not be a good idea..
Include files are for definitions, including class definitions. extern is for variables.
If you don't have the definition of a class in a source file, about the only thing you can do with it is declare it with class Outside; and pass instances around by pointer. You can't actually do anything with the instances, including construction, destruction, or calling member functions like GetCount(). For this, you don't need extern at all; only if you want to refer to a variable in another source file, and that won't let you do anything additional with it.
There is no valid reason not to use #include here. The only alternative is to copy-and-paste the header file into the source file, and that's considerably worse. Anybody who tells you not to use #include does not understand C++, and obviously anybody who thinks extern has any relevance here certainly doesn't.
If at all possible, you should get an experienced C++ developer to help you learn, establish good coding styles, and mentor you in how to develop C++. I suspect you're doing other things that will turn out to be Bad Ideas later on.
If you had a silly requirement that #include is not allowed then you'd have to copy and paste the class declaration into your .cpp file. Need I say that'd be a very bad idea?
What is the reason for this requirement? It pains me to advise you how to do this. If you are trying to avoid long #include paths in your source files, this is a build problem not a source code problem.
You should add directories to the include path with the gcc -I option, or whatever the equivalent is for your compiler.
If you are really, really sure about this, you'd want something like this:
framework.cpp
// FIXME: Should #include "outside.h" but not allowed.
class Outside
{
public:
Outside(int count);
GetCount();
// Omitted
// void SomeUnusedMethod();
};
<code for framework.cpp here>
void UseOutside()
{
Outside o(5);
std::cout << o.GetCount() << std::endl;
}
I would then strongly recommend you leave the declaration as is so it's just straight copy-and-pasted from the header file. But if you want to trim it you can omit any non-virtual methods you don't use. You'll need to keep all variables.
I can only think of one use case where you could 'extern' a class without either #including the header or duplicating the class definition as others have suggested.
If you need to keep pointer to the class but you never dereference it directly, only pass it around, then you can do the following in your file:
class Outside;
class MyClass
{
Outside* pOutside;
void SetOutsidePointer(Outside *p) {pOutside = p;}
Outside* GetOutsidePointer() { return pOutside;}
/* the rest of the stuff */
}
This will only work if you never call pOutside->GetCount() or new Outside in your file.
Put the include for your Outside class in the StdAfx.h or any other headerfile that framework.cpp is already including.
I think you misunderstand the storage classes and one of them is the external.
"Objects and variables declared as extern declare an object that is defined in another translation unit or in an enclosing scope as having external linkage."
So marking extern is for variables not classes defination/declaration
So if you can not include the .h, I recommend you to build the .h and .cpp to be static lib or dll and use in your code
Yikes... we put classes in header files and use #include in order to duplicate class (or other) declarations into multiple cpp files (called compilation units).
If you really can't use #include, you're left with a manual copy, as suggested above, which has the obvious problem of becoming outdated when someone changes the original. That'll completely break your test code with hard to track crashes.
If you insist on going down the path of this manual copy, you do need the entire class declaration. Technically, you could omit certain bits and pieces, but this is a bad idea -- clearly your team doesn't have deep understanding of C++ constructs, so you're likely to make a mistake. Second, the C++ object model is not standardized across compilers. Theoretically even a simple non-virtual method could change the model, breaking your test.
A "long path" is really not a great reason not to include a file directly. But if you really can't, copy the entire header file in where #include would have been -- that's exactly what the C preprocessor is going to do anyway.