我大部分时间只和C一起工作,并且在C++中遇到了一些不熟悉的问题.
假设我在C中有这样的函数,这是非常典型的:
int some_c_function(const char* var)
{
if (var == NULL) {
/* Exit early so we don't dereference a null pointer */
}
/* The rest of the code */
}
Run Code Online (Sandbox Code Playgroud)
让我们说我正在尝试用C++编写类似的函数:
int some_cpp_function(const some_object& str)
{
if (str == NULL) // This doesn't compile, probably because some_object doesn't overload the == operator
if (&str == NULL) // This compiles, but it doesn't work, and does this even mean anything?
}
Run Code Online (Sandbox Code Playgroud)
基本上,我所要做的就是在使用NULL调用some_cpp_function()时防止程序崩溃.
使用对象C++执行此操作的最典型/常用方法是什么(不涉及重载==运算符)?
这甚至是正确的方法吗?也就是说,我不应该编写将对象作为参数的函数,而是编写成员函数吗?(但即使如此,请回答原始问题)
在一个引用一个对象的函数或一个采用C风格指针指向一个对象的函数之间,是否有理由选择一个而不是另一个?
大多数人使用像这样的指针......
if ( p != NULL ) {
DoWhateverWithP();
}
Run Code Online (Sandbox Code Playgroud)
但是,如果指针因任何原因为空,则不会调用该函数.
我的问题是,如果不检查NULL可能更有益吗?显然,在安全关键系统上,这不是一个选项,但是如果程序在没有它的情况下仍可以运行,那么你的程序崩溃的荣耀比没有被调用的函数更明显.
关于第一个问题,在使用指针之前是否总是检查NULL?
其次,考虑你有一个将指针作为参数的函数,并且在整个程序的多个指针上多次使用此函数.你是否发现在函数中测试NULL更有利(好处是你不必在整个地方测试NULL),或者在调用函数之前在指针上测试(这样做的好处就是调用函数没有任何开销) )?
让我们说你有这样的事情:
int& refint;
int* foo =0;
refint = *foo;
Run Code Online (Sandbox Code Playgroud)
你怎么能验证引用是否是NULL为了避免崩溃?
只是为了提供上下文,这是我的代码的简单版本:
class myqueue
{
struct readable
{
readable()
{
static int __next = 0;
id = __next++;
}
int id;
};
std::list<readable> readers;
public:
readable& sub(){
readers.emplace_back();
return readers.back();
}
void unsub(readable& reader)
{
for (auto it = readers.begin(); it != readers.end(); ++it)
{
if (it->id == reader.id)
{
readers.erase(it);
break;
}
}
}
};
int main()
{
myqueue q;
auto& read = q.sub();
q.unsub(read);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,在调用 后unsub(),您从中获得的引用sub()不再有效,对吗?
是否有更好(安全)的方法来处理这种情况并确保没有人会继续使用该引用?
我能想到的第一个替代方案是使用指针而不是引用在运行时检查有效性,但这是您每次都必须明确执行的操作,您也可以跳过/忘记它。如果能够在编译时捕获该引用的任何使用unsub()(就像 Rust 在移动对象后所做的那样),那就太好了。 …