什么是什么时候没有必要检查空?
我最近一直在研究的许多继承代码都有空检查令人作呕.Null检查普通函数,对表示非空返回的API调用进行空检查等.在某些情况下,空检查是合理的,但在许多地方,null不是合理的期望.
我听过很多论点,从"你不能相信其他代码"到"总是防守程序"到"直到语言保证我的非空值,我总会检查." 我当然同意这些原则中的许多原则,但我发现过多的空值检查会导致其他通常违反这些原则的问题.顽强的空检查真的值得吗?
通常,我观察到过多的空检查代码实际上质量较差,而不是质量较高.许多代码似乎都专注于空检查,开发人员已经忽略了其他重要的特性,例如可读性,正确性或异常处理.特别是,我看到很多代码忽略了std :: bad_alloc异常,但对a进行了空检查new.
在C++中,由于解除引用空指针的不可预测行为,我在某种程度上理解这一点; 在Java,C#,Python等中更优雅地处理null dereference.我刚刚看到了警惕的空检查的不良例子,还是真的有什么东西可以解决这个问题?
这个问题旨在与语言无关,尽管我主要对C++,Java和C#感兴趣.
我见过的一些空检查的例子似乎过多,包括:
这个例子似乎是非标准编译器的原因,因为C++规范说失败的新抛出异常.除非您明确支持不合规的编译器,否则这有意义吗?这确实让任何意义的,如Java或C#(甚至C++/CLR)托管语言?
try {
MyObject* obj = new MyObject();
if(obj!=NULL) {
//do something
} else {
//??? most code I see has log-it and move on
//or it repeats what's in the exception handler
}
} catch(std::bad_alloc) {
//Do something? normally--this code is wrong as it allocates
//more memory and will likely fail, such as writing to a log file.
} …Run Code Online (Sandbox Code Playgroud) 我正在编写一个将文件读入内存的C库.它会跳过文件的前54个字节(标题),然后将余数作为数据读取.我使用fseek来确定文件的长度,然后使用fread来读取文件.
循环运行一次然后结束,因为达到了EOF(没有错误).最后,bytesRead = 10624,ftell(stream)= 28726,缓冲区包含28726个值.我希望fread读取30,000字节,当达到EOF时文件位置为30054.
C不是我的母语所以我怀疑我在某个地方有一个愚蠢的初学者错误.
代码如下:
const size_t headerLen = 54;
FILE * stream;
errno_t ferrno = fopen_s( &stream, filename.c_str(), "r" );
if(ferrno!=0) {
return -1;
}
fseek( stream, 0L, SEEK_END );
size_t bytesTotal = (size_t)(ftell( stream )) - headerLen; //number of data bytes to read
size_t bytesRead = 0;
BYTE* localBuffer = new BYTE[bytesTotal];
fseek(stream,headerLen,SEEK_SET);
while(!feof(stream) && !ferror(stream)) {
size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-bytesRead,stream);
bytesRead+=result;
}
Run Code Online (Sandbox Code Playgroud)
根据您使用的参考,很明显在模式标志中添加"b"就是答案.寻求骷髅徽章的提名.:-)
该引用在第二段,第二句(虽然不在他们的表中)中讨论它.
MSDN直到页面中间才讨论二进制标志.
OpenGroup提到了"b"标签的存在,但声明它"应该没有效果".
我试图将模板编程(以及在未来的某些方面,模板元编程)应用于现实世界的场景.我发现的一个问题是C++模板和多态并不总是按照我想要的方式一起玩.
我的问题是,我试图应用模板编程的方式是不正确的(我应该使用普通的旧OOP),或者我是否仍然坚持OOP思维模式.
在这种特殊情况下,我试图使用策略模式解决问题.我一直遇到这样的问题,我最终想要一些表现形式多样的模板似乎不支持.
OOP代码使用组成:
class Interpolator {
public:
Interpolator(ICacheStrategy* const c, IDataSource* const d);
Value GetValue(const double);
}
void main(...) {
Interpolator* i;
if(param==1)
i = new Interpolator(new InMemoryStrategy(...), new TextFileDataSource(...));
else if(param==2)
i = new Interpolator(new InMemoryStrategy(...), new OdbcDataSource(...));
else if(param==3)
i = new Interpolator(new NoCachingStrategy(...), new RestDataSource(...));
while(run) {
double input = WaitForRequest();
SendRequest( i->GetValue(input));
}
}
Run Code Online (Sandbox Code Playgroud)
潜在模板版本:
class Interpolator<class TCacheStrategy, class TDataSource> {
public:
Interpolator();
Value GetValue(const double); //may not be the best way but
void ConfigCache(const& …Run Code Online (Sandbox Code Playgroud) 在Java中,是否有一种优雅的方法来检测在运行finally块之前是否发生了异常?处理"close()"语句时,通常需要在finally块中进行异常处理.理想情况下,我们希望保留两个异常并将它们传播(因为它们都可能包含有用的信息).我能想到的唯一方法是在try-catch-finally范围之外设置一个变量来保存对抛出异常的引用.然后使用finally块中发生的任何内容传播"已保存"的异常.
有更优雅的方式吗?也许API调用会揭示这个?
这是我正在谈论的一些粗略代码:
Throwable t = null;
try {
stream.write(buffer);
} catch(IOException e) {
t = e; //Need to save this exception for finally
throw e;
} finally {
try {
stream.close(); //may throw exception
} catch(IOException e) {
//Is there something better than saving the exception from the exception block?
if(t!=null) {
//propagate the read exception as the "cause"--not great, but you see what I mean.
throw new IOException("Could not close in finally block: " + e.getMessage(),t);
} else …Run Code Online (Sandbox Code Playgroud) 有没有办法绕过或删除另一个线程持有的文件锁而不杀死线程?
我正在我的应用程序中使用第三方库,该库对文件执行只读操作.我需要第二个线程同时读取文件以提取第三方库未公开的一些额外数据.不幸的是,第三方库使用读/写锁打开文件,因此我得到通常的"进程无法访问文件...因为它正被另一个进程使用"异常.
我想避免使用我的线程预加载整个文件,因为文件很大并且会导致加载此文件和超出内存使用量的不必要的延迟.由于文件的大小,复制文件是不实际的.在正常操作期间,两个线程命中同一文件不会导致任何重大的IO争用/性能问题.我不需要在两个线程之间进行完美的时间同步,但是它们需要在相隔半秒的时间内读取相同的数据.
我无法更改第三方库.
这个问题有没有解决方法?
我有2个Lat Long格式的坐标.
我如何从A点(例如纽约37.149472,-95.509544)确定指向B点的方向(例如多伦多40.714269,-74.005973)
我正在寻找像"340 Degrees"这样的价值
在C#中
这是一个noob问题抱歉:(我不知道为什么这会给我一个错误..有人可以解释一下吗?例如我想做:
vector<double> a;
string s("0.11 11.0002");
copys(s, a);
template <typename T, typename S>
void copys(T& c, S& d)
{
istringstream iss(c);
copy(istream_iterator<S>(iss), istream_iterator<S>(),
back_inserter(d));
return;
}
Run Code Online (Sandbox Code Playgroud)
编译器的错误是:
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stream_iterator.h: In member function `void std::istream_iterator<_Tp, _CharT, _Trai
ts, _Dist>::_M_read() [with _Tp = std::vector<double, std::allocator<double> >, _CharT = char, _Traits = std::char_traits<char>, _Dist
= int]':
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/c++/bits/stream_iterator.h:68: instantiated from `std::istream_iterator<_Tp, _CharT, _Trait
s, _Dist>::istream_iterator(std::basic_istream<_CharT, _Traits>&) [with _Tp = std::vector<double, std::allocator<double> >, _CharT = ch
ar, _Traits = std::char_traits<char>, _Dist = int]'
ProfitCalculator.cpp:20: instantiated from …Run Code Online (Sandbox Code Playgroud)