自从我使用Java以来已经至少5年了,当时,只要你想分配一个需要清理的对象(例如套接字,数据库句柄),你就必须记得添加一个finally块并调用清理方法.那里.
相比之下,在C++(或其他对象生命周期是确定性的语言,例如Perl)中,类实现者将定义一个析构函数,只要该类的对象超出范围,该函数就会执行清理.这种方法的优点是对象的用户不会忘记清理它 - 即使抛出异常,也会自动调用析构函数.这种方法以RAII的相当可怕的名字命名 - "资源获取是初始化".
根据我的经验,做"RAII方式"的事情在不必担心是否以及何时发生资源解除分配方面为我节省了大量精神开销.我们正在考虑将Java用于一个中型项目,我想知道自从我上次查看它以来,语言中添加的许多新功能是否存在某种确定性破坏.(我希望因为我的抱怨"Java没有RAII" 在这个帖子上被斥责,但到目前为止我还没能通过谷歌搜索找到任何细节.)
所以,如果有人能够指出一些关于如何在Java中实现这一目标的介绍性材料,那就太棒了!
我想将一些数据从一个表移动到另一个表(可能有不同的模式).想到的直接解决方案是 -
start a transaction with serializable isolation level;
INSERT INTO dest_table SELECT data FROM orig_table,other-tables WHERE <condition>;
DELETE FROM orig_table USING other-tables WHERE <condition>;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
现在如果数据量相当大并且<condition>计算成本昂贵怎么办?在PostgreSQL中,RULE或存储过程可用于动态删除数据,仅评估条件一次.哪种解决方案更好?还有其他选择吗?
我有一个我自己的小头文件,它声明了几个函数,其中一个函数的返回类型为DWORD.我不愿意windows.h只是为了获得这种类型的官方定义,因为该文件非常庞大,我的标题将用于许多其他方式不需要它的源模块.
当然,在实践中我知道这DWORD只是unsigned int,但我更愿意采用更卫生的方法来包含官方头文件(如果可能的话).
在这个页面上它表示DWORD已定义windef.h,但不幸的是,只包含这个小文件直接导致编译错误 - 显然它希望被其他标题包含.(另外,我的文件是头文件的事实也意味着我不能只声明WIN32_LEAN_AND_MEAN,因为#includes我的文件的源文件可能需要保留未定义.)
有任何想法吗?我知道这不是世界末日 - 我可以继续#include <windows.h>- 但认为有人可能有更好的主意!
[编辑] 感谢您的回复.对于那些建议使用不同类型的人,让我解释为什么在这种情况下不可取:我在不同的源文件中设置了两个函数的不同平台特定版本,并要求CMake配置检测当前平台并选择要构建的那个.在Windows上,我的功能如下:
typedef DWORD TimePoint;
TimePoint GetTimeNow(void);
double TimeDifference(TimePoint start, TimePoint end);
Run Code Online (Sandbox Code Playgroud)
Windows版本GetTimeNow()只调用timeGetTime()具有返回类型的Windows API ,DWORD因此它必须具有相同的返回类型.(在其他平台上,TimePoint将有一个不同的类型,例如struct timeval在UNIXy平台上.)实际上,类型的值TimePoint是不透明的,你可以用它们做的唯一事情就是传递它们中的两个TimeDifference()来测量它们之间的经过时间(以秒为单位) .这实现了跨平台开发.不幸的是,它仍然意味着客户端代码必须知道具体类型TimePoint.
我正在玩Levenshteins编辑距离算法,我想扩展它来计算换位 - 即相邻字母的交换 - 作为1编辑.未修改的算法计算从另一个字符串到达某个字符串所需的插入,删除或替换.例如,从"KITTEN"到"SITTING"的编辑距离是3.这是维基百科的解释:
按照相同的方法,从"CHIAR"到"CHAIR"的编辑距离为2:
我想把它算作"1编辑",因为我只交换两个相邻的字母.我该怎么做呢?
人们经常使用attach()和detach()功能建立在R参数名"搜索路径",但由于这种改变是很难跟踪,全局状态的人建议使用with()替代,其临时改变设置的搜索路径,持续时间一个表达式.
但是我只是注意到,不像attach(),with()显然没有"解决"功能.例如,让我们首先设置一个虚函数,它将访问一个名为的变量x:
f <- function { print(x) }
Run Code Online (Sandbox Code Playgroud)
现在,
with(list(x=42), f())
Run Code Online (Sandbox Code Playgroud)
尽管失败了
with(list(x=42), print(x))
Run Code Online (Sandbox Code Playgroud)
和
attach(list(x=42))
f()
Run Code Online (Sandbox Code Playgroud)
都成功了!:(
谁能告诉我为什么?我想with()表现得像attach()在这里一样,通过设置包含参数值的环境,使我能够有效地将大参数列表传递给函数with().我认为这种方法比替代方案有几个好处(我考虑过的两个方法是(a)费力地将所有参数传递给函数,以及(b)明确地将参数列表/框架作为函数参数传递并具有函数本身调用with()),但它不起作用.老实说,我发现这种差异非常麻烦!任何解释/帮助将不胜感激.
我正在使用R 2.11.1.
我知道,在Perl中的子程序,它保留了"默认变量"一个很好的想法$_与local做任何事的,如果之前调用者正在使用它,例如:
sub f() {
local $_; # Ensure $_ is restored on dynamic scope exit
while (<$somefile>) { # Clobbers $_, but that's OK -- it will be restored
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,通常你$_首先使用的原因是因为你想使用正则表达式,这可能会将结果放在方便的"魔法"变量中$1,$2等等. 我也想保留这些变量,但是我还没有能够找到一种方法来做到这一点.
所有perlvar都说,@+并且@-,$1等等似乎依赖于内部,请参考"当前活动动态范围中最后成功的子匹配".但即使这似乎与我的实验不一致.根据经验,以下代码按照我的希望打印"aXaa":
$_ = 'a';
/(.)/; # Sets $1 to 'a'
print $1; # Prints 'a'
{
local $_; # Preserve $_
$_ = 'X';
/(.)/; # Sets $1 to 'X' …Run Code Online (Sandbox Code Playgroud) 因为GNUmake允许变量与内存允许的一样大,所以构建大量依赖列表没有问题.但是,如果要在配方中实际使用这些文件列表(用于构建目标的shell命令序列),则会遇到问题:命令可能超出shell的命令行长度限制,从而产生错误,例如"参数"列表太长了".
例如,假设我想连接列表中包含的几个文件$(INPUTS)以生成文件combined.txt.通常,我可以使用:
combined.txt: $(INPUTS)
cat $^ > $@
Run Code Online (Sandbox Code Playgroud)
但是,如果$(INPUTS)包含数千个文件,就像在我的情况下那样,调用cat太长并且失败.有没有办法解决这个问题?可以安全地假设存在一些与一个巨大命令具有相同行为的命令序列 - 在这种情况下,一系列cat命令(每个输入文件一个)>>用于追加combined.txt将起作用.但是如何make说服生成这些命令呢?
我有这样的公共接口层次结构:
struct ISwitchable {
/* Obtain pointer to another implemented interface of the same instance. */
virtual int switch(unsigned int interfaceId, void** pInstance) = 0;
};
struct IFoo : public ISwitchable { /* Methods */ };
struct IBar : public ISwitchable { /* Methods */ };
struct IFooBar : public IFoo, public IBar { /* Methods */ };
Run Code Online (Sandbox Code Playgroud)
实现IFooBar的类与工厂函数一起放入dll.客户端代码加载dll,使用工厂函数创建类实例并根据接口使用它们(它们作为头文件提供).
Scheme使用MSVC制作的dll和Borland C++ Builder 6制作的客户端代码可以正常工作.
我将虚拟继承引入层次结构:
struct IFoo : public virtual ISwitchable { /* Methods */ };
struct IBar : public virtual …Run Code Online (Sandbox Code Playgroud) 我正在反对这个错误:
int temp = 0789;
error C2041: illegal digit '8' for base '8'
Run Code Online (Sandbox Code Playgroud)
我能理解的是,编译器将任何以 0 开头的数字(如 0123)理解为八进制。但是我怎么能告诉编译器只在前面加上 0 呢?
algorithm ×2
c++ ×2
c ×1
c++builder ×1
header ×1
java ×1
makefile ×1
perl ×1
postgresql ×1
r ×1
raii ×1
scalability ×1
sql ×1
string ×1
visual-c++ ×1
windows ×1