问题
So, I have the following in a specification file
#include <string>
#include <fstream>
using namespace std:
class MyStuff
{
private:
string name;
fstream file;
// other stuff
public:
void setName(string);
}
I also have in the implementation file
#include \"MyStuff.h\"
using namespace std;
void MyStuff::setName(string name);
{
name = name
}
and in the program file I have...
#include <iostream>
#include <string>
using namespace std;
void main()
{
string name;
MyStuff Stuff;
cout << \"Enter Your Name: \";
getline(cin, name);
Stuff.setName(name);
}
And I\'m gathering that applying \"using namespace std;\" in a header file is a no-no, and that to fully qualify is the \"better\" practice; such as std::cout << stuff << endl;
It is my understanding that in order to use a string, it must have the std namespace. Is that true?
If so, in the header file, is more \"pure/clean\" to do it as...
#include <string>
class MyStuff
{
std::string name;
}
And, as I understand it currently, using namespace std; across all three files, specification, implementation, and program, essentially layers the three namespaces on top of each other, so if I separately declare string name;
within each of the files, the compiler will not know which goes to what. Is that true?
I generally understand that being clear is a \"good\" thing to do, I am however a little unclear on the specificity of how, and I\'m most interested in the deeper \"why\" that underlies it all.
So my direct question is, in my example provided, what is the \"clearest\" way to describe the function both for the compiler and for industry \"standard\"? And, can you direct me to resources that more clearly delineate the reasoning and practical implementation of namespaces.
回答1:
Let's say I declare a class string
myself. Because I'm a lazy bum, I do so in global namespace.
// Solar's stuff
class string
{
public:
string();
// ...
};
Some time later on, I realize that re-using some of your code would benefit my project. Thanks to you making it Open Source, I can do so:
#include <solarstuff.hpp>
#include <phoenixstuff.hpp>
string foo;
But suddenly the compiler doesn't like me anymore. Because there is a ::string
(my class) and another ::string
(the standard one, included by your header and brought into global namespace with using namespace std;
), there's all kinds of pain to be had.
Worse, this problem gets promoted through every file that includes my header (which includes your header, which... you get the idea.)
Yes I know, in this example I am also to blame for not protecting my own classes in my own namespace, but that's the one I came up with ad-hoc.
Namespaces are there to avoid clashes of identifiers. Your header not only introduces MyStuff
into the global namespace, but also every identifier from string
and fstream
. Chances are most of them are never actually needed by either of us, so why dragging them into global, polluting the environment?
Addition: From the view of a maintenance coder / debugger, foo::MyStuff
is ten times more convenient than MyStuff
, namespace'd somewhere else (probably not even the same source file), because you get the namespace information right there at the point in the code where you need it.
回答2:
Multiple instances of using namespace std;
will not cause any ambiguity. The problem is that that statement imports all the names/types/functions of std
into your namespace, and now if you want to name a class string
for instance, you will hit into trouble. This is more likely to happen with functions like remove, erase, etc.
The use of it in headers is one level worse because that propagates to all the .cpp
s that header, without the awareness of person including it. Using it in .cpp
atleast needs a conscious choice.
A more complete explanation can be got at Why is "using namespace std" considered bad practice?
An example of issues that might result from this can be found in How to use an iterator? where the OP defines a function distance
, and keeps getting the wrong answer. Another example at Confusion about pointers and references in C++
回答3:
Namespace usings are for your convenience, not for you to inflict on others: Never write a using declaration or a using directive before an #include directive.
Corollary: In header files, don't write namespace-level using directives or using declarations; instead, explicitly namespace-qualify all names. (The second rule follows from the first, because headers can never know what other header #includes might appear after them.)
I generally understand that being clear is a "good" thing to do, I am however a little unclear on the specificity of how, and I'm most interested in the deeper "why" that underlies it all.
Below code snippets reflects why use using namespace
in header file is bad:
// snippet 1
namespace A {
int f(double);
}
// snippet 2
namespace B {
using A::f;
void g();
}
// snippet 3
namespace A {
int f(int);
}
// snippet 4
void B::g() {
f(1); // which overload is called?
}
So in your example, simply this one is better:
#include <string>
class MyStuff
{
std::string name;
};
Recommend book: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
and link: Google C++ coding guide
来源:https://stackoverflow.com/questions/14575799/using-namespace-std-in-a-header-file