我在C++中使用两个大代码,一个用"C风格"完成,另一个用"C++风格"完成.
C类代码具有返回const char*的函数,而C++代码在很多地方都有类似的东西
const char* somecstylefunction();
...
std::string imacppstring = somecstylefunction();
Run Code Online (Sandbox Code Playgroud)
它从C样式代码返回的const char*构造字符串.
这有效,直到C样式代码更改并开始有时返回NULL指针.这当然会导致seg故障.
周围有很多代码,所以我想以最简约的方式解决这个问题.预期的行为是imacppstring在这种情况下将是空字符串.这有一个很好的,光滑的解决方案吗?
更新
这些函数返回的const char*始终是指向静态字符串的指针.它们主要用于传递有关函数中任何意外行为的信息性消息(最有可能记录日志).决定在"无报告"上返回NULL是很好的,因为那时你可以使用返回值作为条件,即
if (somecstylefunction()) do_something;
Run Code Online (Sandbox Code Playgroud)
而在函数返回静态字符串""之前;
这是否是一个好主意,我不打算触及这个代码,无论如何这都不取决于我.
我想避免的是跟踪每个字符串初始化以添加包装函数.
Mic*_*urr 13
可能最好的做法是将C库函数修复为其破坏前的更改行为.但也许你无法掌控那个图书馆.
要考虑的第二件事是更改所有依赖于C lib函数的实例,返回一个空字符串以使用一个"修复"NULL指针的包装函数:
const char* nullToEmpty( char const* s)
{
return (s ? s : "");
}
Run Code Online (Sandbox Code Playgroud)
所以现在
std::string imacppstring = somecstylefunction();
Run Code Online (Sandbox Code Playgroud)
可能看起来像:
std::string imacppstring( nullToEmpty( somecstylefunction());
Run Code Online (Sandbox Code Playgroud)
如果这是不可接受的(可能是繁忙的工作,但它应该是一次性的机械更改),您可以实现一个"并行"库,其名称与您当前使用的C lib相同,函数只是调用原始的C lib函数并根据需要修复NULL指针.您需要使用标题,链接器和/或C++命名空间来玩一些棘手的游戏才能使其正常工作,这有可能造成混乱,所以在走这条路之前我会认真思考.
但是类似下面的内容可能会让你开始:
// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
const char* somecstylefunction();
}
// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
const char* somecstylefunction() {
const char* p = ::somecstylefunction();
return (p ? p : "");
}
}
Run Code Online (Sandbox Code Playgroud)
现在你只需要将那个头添加到当前正在调用C lib函数的.cpp文件中(并且可能删除C lib的头文件)并添加一个
using namespace clib_fixer;
Run Code Online (Sandbox Code Playgroud)
使用这些函数到.cpp文件.
那可能不会太糟糕.也许.
好吧,没有改变C++ std::string直接从C函数调用初始化的每个地方(添加空指针检查),唯一的解决方案是禁止C函数返回空指针.
在GCC编译器中,您可以使用编译器扩展"Conditionals with Omitted Operands"为C函数创建包装器宏
#define somecstylefunction() (somecstylefunction() ? : "")
Run Code Online (Sandbox Code Playgroud)
但一般情况下我会反对.