Char array pointer vs string refrence in params
I 开发者_Go百科often see the following structure, especially in constructors:
class::class(const string &filename)
{
}
class::class(const char * const filename)
{
}
By step-by-step debug, I found out the 2nd constructor is always called if I pass a hard-coded string.
Any idea:
1) Why the dual structure is used?
2) What is the speed difference?
Thanks.
Two constructors are needed because you can pass a NULL
to your MyClass::MyClass(const std::string &arg)
. Providing second constructor saves you from a silly crash.
For example, you write constructor for your class, and make it take a const std::string &
so that you don't have to check any pointers to be valid if you'd be using const char*
.
And everywhere in your code you're just using std::string
s. At some point you (or another programmer) pass there a const char*
. Here comes nice part of std::string
- it has a constructor, which takes char*
, and that's very good, apart from the fact, that std::string a_string(NULL)
compiles without any problems, just doesn't work.
That's where a second constructor like you've shown comes handy:
MyClass::MyClass(const char* arg)
: m_string(arg ? arg : "")
{}
and it will make a valid std::string
object if you pass it a NULL
.
In this case I don't think you'd need to worry about any speed. You could try measuring, although I'm afraid you'd be surprised with how little difference (if any) there would be.
EDIT: Just tried std::string a_string(NULL);
, compiles just fine, and here's what happens when it is run on my machine (OS X + gcc 4.2.1) (I do recall I tried it on Windows some time ago, result was very similar if not exactly same):
std::logic_error: basic_string::_S_construct NULL not valid
This is useful if the implementation deals with const char*
s by itself, but is mostly called by std::string
users. These can call using the std::string
API, which usually just calls c_str()
and dispatches to the const char*
implementation. On the other side, if the caller does already have a c-string, no temporary or unneeded std::string
needs to be constructed (which can be costly, for longer strings it's a heap allocation).
Also, I once used it to resolve the following case:
My interface took std::string
's, but had to be implemented in an external module, thus the STL binary versions of both the module AND the caller module had to match exactly, or it would have crashed (not really good for a portable library… ). So I changed the actual interface to use const char*
, and added std::string
overloads which I declared inline
, so they weren't exported. It didn't break existing code, but resolved all my module boundary problems.
1) Why the dual structure is used?
The string reference version is required if std::string objects are to be used conveniently as parametersm as there is no implicit conversion from a std::string to a const char const. The const char * const version is optional, as character arrays can implicitly be converted into std::strings, but it is more efficient, as no temporary std::string need be created.
2) What is the speed difference?
You will need to measure that yourself.
They are offered basically for convenience. Some times, if you call C functions, you get char* pointers. Others, you get strings, so offering both constructors is just a convenience for the caller. As for the speed, both have virtually the same speed, as they both send a memory address to the constructor.
精彩评论