天天看点

将NULL传递给C++字符串形参

考虑如下代码:

void myfunc(string str)

{

}

显然,这个函数需要传入一个字符串参数。因此下面是调用此函数的方法。

myfunc("abc");

但是,如果我们要传入一个NULL呢?

myfunc(NULL);

砰!程序出错了!C++的basic_string的构造函数不允许NULL值。

当然,我们可以传入一个空字符串。

myfunc("");

或者,传入一个空字符串对象。

string a;

myfunc(a);

但这些都不是以NULL值作参数来传递。

既然可以变通,为何一定要传入NULL值呢?设有一个规范。

void createBook(string title);

规范要求,title是一个字符串,可以为null.

规范设计者显然是使用Java语言的,因此使用Java语言可以安全地传入null值。

但若用C++语言来实现此规范,就遇到上面的问题了。即使像上面一样传入空字符串,它也不是NULL值。规范要求,必须允许传入NULL值。

使用C++11的shared_ptr<string>,可以解决此问题。

void myfunc(shared_ptr<string> str)

{

}

myfunc(NULL);

但是,新问题来了,

myfunc("abc");  // error: No matching function for call to 'myfunc'

对于类型是shared_ptr<string>的参数,必须使用make_shared<string>()生成shared_ptr<string>后再传入。于是有了下面的代码:

myfunc(make_shared<string>("abc"));

下面是目前为止,行之有效的代码:

void myfunc(shared_ptr<string> str)

{

}

myfunc(NULL);

myfunc(make_shared<string>("abc"));

每次都要输入shared_ptr<string>,或make_shared<string>,不够简短。下面来简化代码的输入。

第一,由于shared_ptr<string>是类型,可以使用typedef来简化它。

typedef shared_ptr<string> MyString;

void myfunc(MyString str) {

}

第二,make_shared<string>是一个模板方法,可以通过引入一个名称较短的函数来替换它。

shared_ptr<string> MMS(string str)

{

    return make_shared<string>(str);

}

myfunc(MMS("abc"));

MMS表示Make MyString的意思。但是,增加的函数调用也同时增加了程序的负担。另一方法是使用#define来定义一个宏。

#define MMS(...) make_shared<string>(__VA_ARGS__)

myfunc(MMS("abc"));

省略号...表示__VA_ARGS__所传入的参数是字符串。因此,完全适合这里的需要。下面是实现后的全部代码。

#define MMS(...) make_shared<string>(__VA_ARGS__) typedef shared_ptr<string> MyString;

void myfunc(MyString str) {

}

myfunc(NULL);

myfunc(nullptr);

myfunc(MMS("abc"));

代码简短了许多,最主要的,它支持了将NULL值传入给字符串形参。

此外,使用shared_ptr<string>还有一个好处,就是不需要显式地手工清理内存。

void myfunc(shared_ptr<string> str)

{

    // use pointer str     cout << str->length() << endl;

    // delete pointer str is NOT necessary

}  // pointer str will be deleted automatically here

继续阅读