C++ Redefining variables of a namespace? - c++

I've got two questions.
Question 1: Can someone provide an example of how to define/redefine a variable in a namespace. I've provided my own guess for you to base an your answer from.
// namespace.hpp
namespace example
{
static string version;
static int x;
}
And then in a .cpp how do I redefine those variables?
// namespace.cpp
namespace example
{
version = "0.1"; // ?????
x = 0; //???
}
Question 2: How would I attach a permanent class object onto a namespace from the same .hpp file? Something like this:
// namespace.hpp
class Idk
{
public:
int doThis();
}
namespace example
{
Idk idkObject;
}
The code above, when included multiple times (from different files) will replace the object, which will cause compilation errors. Once again, I need a permanent way to attach a object to a namespace its header file.

Instead of 'static', write 'extern' in the header file and include the data type in the variable definitions in the cpp file.

Question 1: You need to specify the type also
// namespace.cpp
namespace example
{
string version = "0.1"; // ?????
int x = 0; //???
}
Question 2: You shouldn't create a 'non-static' object in a header file irrespective of the namespace. You should just use static here also or else you should use extern in header file and define the variable inside a cpp file. {Note it's a little different with templatized classes}
// namespace.hpp
class Idk
{
public:
int doThis();
}
namespace example
{
static Idk idkObject;
}
// namespace.cpp
namespace example
{
Idk idkObject; // Default constructor
}

Related

Anonymous namespace in template implementation file

In a .cpp file, an anonymous namespace basically has file-wide linkage (after #includes) because the .cpp file will never be included by another file. But, the same pattern in a header file propagates that anonymous namespace to wherever it is included in. Is there a way to create a similar effect in a header file? I ask because template implementations must be in headers.
A simple example in a regular .h file would be this:
// object.h
namespace {
using verbose::namespace::type;
}
...
struct object {
type value;
}
or similarly in some template implementation file. The type type would be in-scope of wherever this file is included.
Is there a way around this?
EDIT: I think I found a verbose but workable answer.
// object.h
struct Namespace {
using verbose::namespace::type;
Namespace() = delete;
struct object {
type value;
};
};
using Namespace::object;
This should do the trick:
// object.h
{
namespace {
using verbose::namespace::type;
}
...
struct object {
type value;
}
}
Namespaces should only be valid within the code block they're defined in.

C++ member function definition outside the class | duplicate symbols

In one of my classes header file Lfo.h, I have a class definition where I put the member function definition out of the class (It might be better to have a separate .cpp file but it should be ok put here?):
// Lfo.h
class CLfo
{
public:
static int create (CLfo*& pCLfo);
};
int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
Then I have another class called CVibrato:
// Vibrato.h
class CVibrato
{
public:
static int create (CVibrato*& pCVibrato);
private:
CVibrato();
};
and the .cpp file (in the cpp file, I include Lfo.h because later on the vibrato class will have a lfo member but I haven't implemented right now):
// Vibrato.cpp
#include "Lfo.h"
#include "Vibrato.h"
int CVibrato::create(CVibrato *&pCVibrato)
{
pCVibrato = new CVibrato();
return 0;
}
CVibrato::CVibrato()
{
}
Then I want to create a instance of vibrato class in main()
#include "Vibrato.h"
#include "Lfo.h" // if comment this line out there will be no error, why is that?
int main()
{
CVibrato *vibrato = 0;
CVibrato::create(vibrato);
return 0;
}
However I get a 1 duplicate symbol for architecture x86_64 error. What is duplicated? It seems the reason is in Lfo.h, I put the definition of the member function outside of the class, if I put it inside, the program runs properly. But I cannot understand. In c++, aren't we allowed to do this? By the way, if one of my class (in my case vibrato) is going to have a class member of another class (in this case lfo), should I include the header file of member class in .h (vibrato.h) file or .cpp (vibrato.cpp) file?
Classes are declarations. No code is produced from a declaration. Even if you have a member function in the class, it is treated as if an inline by the compiler. Function bodies can be put in a header but should always be declared as inline. The compiler may not actually inline it, but it will treat it as a single instance for code creation.
Any time you:
void function( ) { }
Code is created for that function. If a header is included more than once the compiler is told to create the code more than once. But all functions must have unique names! So you get the duplicate error. That is why code generating lines belong in the .cpp files.
'inline' tells the compiler not to create immediate code but to create the code at the usage point.
You can't put class method definition directly in a header file, unless you explicitly mark it as inline. Like the following:
// Lfo.h
class CLfo
{
public:
inline static int create (CLfo*& pCLfo);
};
int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}
Or,
// Lfo.h
class CLfo
{
public:
static int create (CLfo*& pCLfo);
};
inline int CLfo::create(CLfo *&pCLfo)
{
pCLfo = new CLfo;
return 0;
}

How to make a variable available to multiple .cpp files using a class?

This question has derived from this one.
I have a working program which must be split into multiple parts. In this program is needed to use a variable (now it's a GTK+ one :P) many times in parts of the program that will end up in separated .cpp files.
So, I made a simple example to understand how to make variables available to the program parts. A modified version of the previous code would be:
#include <iostream>
using namespace std;
int entero = 10;
void function()
{
cout<<entero<<endl;
//action1...;
}
void separated_function()
{
cout<<entero<<endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
It is needed to split the code correctly, to have function(), another_function() and main() in separated .cpp files,and make entero avaliable to all of them... BUT:
In the previous question #NeilKirk commented:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (And I also have found many web pages pointing that is not recommended to use global variables).
And, as far I can understand, in the answer provided by #PaulH., he is describing how to make variables avaliable by making them global.
This answer was very useful, it worked fine not only with char arrays, but also with ints, strings and GTK+ variables (or pointers to variables :P).
But since this method is not recommended, I would thank anyone who could show what would be the correct way to split the code passing the variables as a function parameter or some other method more recommended than the - working - global variables one.
I researched about parameters and classes, but I'm a newbie, and I messed the code up with no good result.
You need to give the parameter as a reference if you want the same comportement as a global variable
#include <iostream>
using namespace std;
// renamed the parameter to avoid confusion ('entero' is valid though)
void function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value
//action1...;
}
void separated_function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value again
//action2...;
}
int main( int argc, char *argv[] )
{
int entero = 10; // initializing the variable
// give the parameter by reference => the functions will be able to modify its value
function(entero);
separated_function(entero);
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
output:
10
11
12
Defining a class or struct in a header file is the way to go, then include the header file in all source files that needs the classes or structures. You can also place function prototypes or preprocessor macros in header files if they are needed by multiple source files, as well as variable declarations (e.g. extern int some_int_var;) and namespace declarations.
You will not get multiple definition errors from defining the classes, because classes is a concept for the compiler to handle, classes themselves are never passed on for the linker where multiple definition errors occurs.
Lets take a simple example, with one header file and two source files.
First the header file, e.g. myheader.h:
#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice
// Define a namespace
namespace foo
{
// Define a class
class my_class
{
public:
my_class(int val)
: value_(val)
{}
int get_value() const
{
return value_;
}
void set_value(const int val)
{
value_ = val;
}
private:
int value_;
};
// Declare a function prototype
void bar(my_class& v);
}
#endif // MYHEADER_H
The above header file defines a namespace foo and in the namespace a class my_class and a function bar.
(The namespace is strictly not necessary for a simple program like this, but for larger projects it becomes more needed.)
Then the first source file, e.g. main.cpp:
#include <iostream>
#include "myheader.h" // Include our own header file
int main()
{
using namespace foo;
my_class my_object(123); // Create an instance of the class
bar(my_object); // Call the function
std::cout << "In main(), value is " << my_object.get_value() << '\n';
// All done
}
And finally the second source file, e.g. bar.cpp:
#include <iostream>
#include "myheader.h"
void foo::bar(foo::my_class& val)
{
std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
val.set_value(456);
}
Put all three files in the same project, and build. You should now get an executable program that outputs
In foo::bar(), value is 123
In main(), value is 456
I prefer to provide a functional interface to global data.
.h file:
extern int get_entero();
extern void set_entero(int v);
.cpp file:
static int entero = 10;
int get_entero()
{
return entero;
}
void set_entero(int v)
{
entero = v;
}
Then, everywhere else, use those functions.
#include "the_h_file"
void function()
{
cout << get_entero() << endl;
//action1...;
}
void separated_function()
{
cout << get_entero() << endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<< get_entero() <<endl;
//something else with the mentioned variables...;
return 0;
}
If you do not plan to modify the variable, it is generally ok to make it global. However, it is best to declare it with the const keyword to signal the compiler that it should not be modified, like so:
const int ENTERO = 10;
If you are using multiple cpp files, also consider using a header file for your structures and function declarations.
If you are planning on modifying the variable, just pass it around in function parameters.

How to write a HelloWorld header files?

I have the following code in a single cpp file (tested.cpp):
class tested {
private:
int x;
public:
tested(int x_inp) {
x = x_inp;
}
int getValue() {
return x;
}
};
Now I want to write a header file for this code. How should it look? And what should I change in my cpp file after I have a header file. I supposed that my header file should be something like that:
class tested {
private:
int x;
public:
tested(int x);
int getValue();
}
Then in my cpp file I should #include "tested.h". I also need to replace the whole class by:
tested::tested(int c_inp) {
x = x_inp;
}
tested::getValue(){
return x;
}
Is it right?
To make your header file more universal, you could use the macro #ifndef like it is done here
http://www.fredosaurus.com/notes-cpp/preprocessor/ifdef.html
You also need to type the type of return for methods other than constructor and destructor :
int tested::getValue(){
return x;
}
Yep, as freude said before, it is usual to protect header files against multiple inclusions with #ifndef (especially in big projects, or if your file may be part of one).
Some other things (essentially matter of style):
It isn't mandatory to put "private:" for the first members of the class, since all class members are private by default.
It is usual to put a character before (or after) the name of each attribute of the class (e.g. "x_" instead of "x")

Creating a C++ namespace in header and source (cpp)

Is there any difference between wrapping both header and cpp file contents in a namespace or wrapping just the header contents and then doing using namespace in the cpp file?
By difference I mean any sort performance penalty or slightly different semantics that can cause problems or anything I need to be aware of.
Example:
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
namespace X
{
void Foo::TheFunc()
{
return;
}
}
VS
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
using namespace X;
{
void Foo::TheFunc()
{
return;
}
}
If there is no difference what is the preferred form and why?
The difference in "namespace X" to "using namespace X" is in the first one any new declarations will be under the name space while in the second one it won't.
In your example there are no new declaration - so no difference hence no preferred way.
Namespace is just a way to mangle function signature so that they will not conflict. Some prefer the first way and other prefer the second version. Both versions do not have any effect on compile time performance. Note that namespaces are just a compile time entity.
The only problem that arises with using namespace is when we have same nested namespace names (i.e) X::X::Foo. Doing that creates more confusion with or without using keyword.
There's no performance penalties, since the resulting could would be the same, but putting your Foo into namespace implicitly introduces ambiguity in case you have Foos in different namespaces. You can get your code fubar, indeed. I'd recommend avoiding using using for this purpose.
And you have a stray { after using namespace ;-)
If you're attempting to use variables from one to the other, then I'd recommend externalizing them, then initializing them in the source file like so:
// [.hh]
namespace example
{
extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
int a, b, c;
}
// Then in the function below, you can init them as what you want:
void reference
{
example::a = 0;
}
If the second one compiles as well, there should be no differences. Namespaces are processed in compile-time and should not affect the runtime actions.
But for design issues, second is horrible. Even if it compiles (not sure), it makes no sense at all.
The Foo::TheFunc() is not in the correct namespacein the VS-case. Use 'void X::Foo::TheFunc() {}' to implement the function in the correct namespace (X).
In case if you do wrap only the .h content you have to write using namespace ... in cpp file otherwise you every time working on the valid namespace. Normally you wrap both .cpp and .h files otherwise you are in risk to use objects from another namespace which may generate a lot of problems.
I think right thing to do here is to use namespace for scoping.
namespace catagory
{
enum status
{
none,
active,
paused
}
};
void func()
{
catagory::status status;
status = category::active;
}
Or you can do the following:
// asdf.h
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
Then
// asdf.cpp
#include "asdf.h"
void X::Foo::TheFunc()
{
return;
}