ns.cpp:
#include <iostream>
namespace ns { // want to access this globally
class A ;
}
class ns::A {
public:
int x1;
char s1[128];
};
int main()
{
int doit();
//using namespace ns;
ns::A a;
a.x1= 2;
std::cout << "pre " << a.x1 << "\n" ;
doit();
std::cout << "post " << a.x1 << "\n" ;
}
ns_call.cpp:
namespace ns {
class A;
}
class ns::A {
public:
int x1;
char s1[];
};
using namespace ns;
int
doit()
{
extern ns::A a;
a.x1= 100;
}
in ns.cpp, a class is declard within a namespace.
the class is defined followed.
Variables in the class are to be accessed globally. This
is the goal of the namespace.
ns_call.cpp then access 1 of the class' member, x1.
The 2 files were compiled OK with gcc 5.4.1 in Fedora 14.
run output is:
pre 2
post 2
I expected 'post 100' because i wanted to access int x1 in class A
globally.
None of extern, namespaces or forward declarations seem to mean what you think they mean.
If you want to introduce a name that can be accessed my multiple translation units (what you seem to mean when you say "globally"), you put those definitions in a header file, and #include that header from wherever you want to use it.
What you're actually doing is introducing class A over and over again in every translation unit (eg, in each CPP file). This is a violation of the ODR at best.
I'm just gonna help you fix your problem, while you absolutely have to heed the other answers about ODR (One Definition Rule) and fix your design.
in the ns.cpp file, you have to move the line ns::A a; out of the main() function. Put it at the file scope (e.g. right before main.) Also, in the ns_call.cpp file, move the line extern ns::A a; out of the function too.
Note: you may or may not have to do the second part, and this whole method might or might not work. I don't have access to a compiler right now.
Again I have to agree with other comments that this design is flawed and it will cause you headaches.
Related
I'm aware of using function prototypes, and I was under the impression that forward class declarations could serve a similar purpose when main() and a class are in the same file. For example, I would have expected this would compile:
// main.cpp
#include <iostream>
// class prototypes
class MyClass;
int main(void)
{
MyClass myClass;
// do stuff with myClass here
return(0);
}
class MyClass
{
public:
int someInt;
double someDouble;
// more stuff here . . .
};
But on the MyClass myClass; line I'm getting the error 'myClass' uses undefined class 'MyClass'. What am I doing wrong?
P.S. I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
P.P.S. I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
Forward declarations can only be used via pointers or references.
Calling a constructor function doesn't fall into this category.
I'm aware that I could cut/paste main() below all the classes it uses and that would fix the error, but I'd prefer to keep main() as the first function or class.
That's why usually header files are used, instead of placing all the declarations and definitions in the main.cpp file.
I'm aware that in any substantial size production program main(), .h content, and .cpp content would be in 3 separate files. In this case I'm attempting to write a small example or test program where main and a class(es) are in the same file.
You should still stick to that idiom though, everything else would probably end up in a mess.
This doesn't use forward declarations but it partially addresses the spirit of a single main.cpp with your "main" at the top. I find this technique sometimes useful when you want to share something via an online C++ ide where a single file is much easier to deal with, and you want to focus on the action in main rather than implementation detail in helper structs/classes etc.
#include <iostream>
template<typename MyClass,typename MyOtherClass>
int main_()
{
MyClass a;
a.do_foo();
MyOtherClass b;
b.do_bar();
return 0;
}
struct MyClass
{
void do_foo() { std::cout << "MyClass: do_foo called\n"; }
};
struct MyOtherClass
{
void do_bar() { std::cout << "MyOtherClass: do_bar called\n"; }
};
int main()
{
return main_<MyClass,MyOtherClass>();
}
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.
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;
}
Say I have two different cpp files. Both declare classes with the same name, but perhaps a totally different structure (or perhaps the same structure, different implementation). The classes do not appear in the header files. (As an example, suppose they are Node classes for different list classes.)
I've seen these classes conflict. Is this expected by the standard? What solutions are there to this problem?
UPDATE:
As suggested by answers/comments, anonymous namespaces are what I was looking for.
The standard way around this problem is to wrap the classes in different namespaces.
It violates One Definition Rule. It's hard for compiler to detect the error, because they are in different compilation units. And even linker cannot detect all errors.
See an example in http://www.cplusplus.com/forum/general/32010/ . My compiler and linker (g++ 4.2.1) can build the final executable without any error, but the output is wrong.
If I change the example a bit, I get segmentation fault.
// main.cpp
#include <iostream>
#include <list>
using namespace std;
struct Handler
{
Handler() : d(10, 1.234) {}
list<double> d;
};
extern void test_func();
int main(void)
{
Handler h;
cout << h.d.back() << endl;
test_func();
return 0;
}
// test.cpp
#include <iostream>
#include <string>
using namespace std;
struct Handler
{
Handler() : d("test Handler") {}
string d;
};
void test_func()
{
Handler h;
cout << h.d << endl;
}
It's recommended to differentiate you class by namespace. For example of Node, you can use nest class and define the Node in the parent list class. Or you can add you class in anonymous namespace. See How can a type that is used only in one compilation unit, violate the One Definition Rule?
I'm not sure if I'm missing some detail here, but you wrap each class in a namespace.
namespace A {
class Node { };
}
namespace B {
class Node { };
}
Then you can use A::Node or B::Node.
You can use namespace to have multiple classes with same name by sub-scoping them in different namespaces. See: http://www.cplusplus.com/doc/tutorial/namespaces/
I've seen these classes conflict. Is this expected by the standard?
The standard says you can't do that. It would violate the one definition rule. (How to fix this has already been covered in other answers)
id.cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
static int a;
};
int A::a=20;
class b
{
public:
b()
{
cout<<A::a<<endl;
}
};
int main()
{
b *b1 = new b();
return 0;
}
id1.cpp
#include "stdafx.h"
#include <iostream>
using namespace std;
class c
{
public:
int get()
{
cout<<A::a<<endl;
}
};
int main()
{
c c1;
c1.get();
return 0;
}
This is the way they have declared and got the output in one program but when I'm trying it I'm getting errors as the class is not a namespace or the program id is not included in the id1 file... How to get the variable that is stored in one file into the other file without using namespace and including the header file is there any option for it?
Two separate programs as shown (they're separate because they both define main()) cannot share variables in any simple way.
If the two separate files were to be integrated into a single program, so one of the main() programs was replaced, then you would fall back on the standard techniques of declaring the variable A::a in a header and using that header in both modules. The header would also define class A. This is the only sane way to do it.
You could write the definition of the class twice, once in each file, and declare the variable as an extern in one file and define it in the other, but that is not particularly sensible even in this simple case and rapidly degenerates into unmaintainable disaster if the code gets any more complex and there are more shared variables.
Of course, you might want to consider not using a global variable at all, but provide instead an accessor function. However, you still end up with a header declaring the services provided by the class A and the code implementing those services, and the code consuming those services.