小编Ste*_*ler的帖子

可以在调用System.LoadLibrary时捕获UnsatisfiedLinkError以回退到另一个DLL吗?

在启动时,我希望我的Java程序加载一个DLL,该DLL应该在java.library.path定义的路径上.但是,如果缺少该DLL,我希望我的程序回退到加载不同的DLL.如果找不到DLL文件,System.LoadLibrary会抛出UnsatisfiedLinkError.UnsatisfiedLinkError是Error的子类,而不是Exception的子类.很多评论都表明捕捉错误是不好的做法.这是一个可以做这样的事情的情况吗?

try
{
    System.loadLibrary("myLibrary");
}
catch (UnsatisfiedLinkError e)
{
    try
    {
        System.load(<a fully qualified path to my fall-back library>);
    }
    catch (UnsatisfiedLinkError e)
    {
        <report that even the fall-back library didn't load>;
    }
}
Run Code Online (Sandbox Code Playgroud)

java

16
推荐指数
1
解决办法
4559
查看次数

为什么向上转换基类的子指针有时会改变指针值?

我发现了一些似乎与我的问题有关的其他问题,但没有一个直接回答它(即使几乎同名的问题).

我有一个源自两个父母的C++子类.我创建了该类的一个对象,然后将它的引用转换为它的两个父类.转换值不相同,但仍然是子引用的值.这是代码:

class Mom
{
public:
    int a = 1;
};

class Dad
{
public:
    int b = 2;
};

class Child : public Mom, public Dad
{
public:
    int c = 3;
};

int main()
{
    Child* c = new Child; // 0x00C5A618

    Mom* m = c; // 0x00C5A618
    Dad* d = c; // 0x00C5A61C

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,我猜测通过应用static_cast <>获得的地址是实际子对象的地址.碰巧,它Mom是第一个子对象,所以它实际上具有相同的地址Child.Dad是第二个子对象,因此它位于不同的地址.

据我所知,C风格的演员阵容就像这样

Mom* m = (Mom*)c;
Dad* d = (Dad*)c;
Run Code Online (Sandbox Code Playgroud)

如果这样做是合法的,将应用static_cast <>.实际上,当我实际编译并执行该版本时,我会看到与以前相同的行为. …

c++ pointers casting

8
推荐指数
1
解决办法
1063
查看次数

为什么类型推断对于lambda失败,但成功进行等效的方法引用?

我正在使用lambda在下面的Java程序中实现一个功能接口.当lambda作为参数传递给泛型方法时,编译器会标记"不兼容类型"错误,因为它推断lambda实现了Func <Shape>接口,该接口让编译器将lambda参数("thing")解释为当lambda尝试将其传递给需要Round类型参数的方法(testRound)时,为Shape类型.这个错误对我有意义.

但是等效方法引用不会引发错误消息.我一直误以为lambda和可以替换lambda的方法引用是可以互换的.在这里,事实并非如此.

public class Main
{
    public static void main(String... args)
    {
        methodB(thing -> Main.testRound(thing)); // incompatible types
        methodB(Main::testRound);                // no problem here
    }

    static <T extends Shape> void methodB(Func<T> function)
    {
    }

    static boolean testRound(Round thing)
    {
        return true;
    }
}

interface Func<T>
{
    boolean test(T ob);
}

class Shape
{
}

class Round extends Shape
{
}
Run Code Online (Sandbox Code Playgroud)

当lambda失败时,为什么方法引用成功?

UPDATE

Vince Emigh在下面找到了我已经标记为接受的答案.虽然这不是我的问题的一部分,但是有四种方法可以解决这样一个事实:Func<Shape>如果一个人真的被使用lambdas ,那么lambda只被推断为类型:

// Use a type witness.

Main.<Round>methodB(thing -> testRound(thing));

// Make the lambda's argument …
Run Code Online (Sandbox Code Playgroud)

java generics lambda type-inference

7
推荐指数
1
解决办法
272
查看次数

为什么Sleep()会使后续代码减速40ms?

我最初在coderanch.com上询问过这个问题,所以如果你试图在那里帮助我,谢谢,并且不觉得有必要重复这些努力.但是,coderanch.com主要是一个Java社区,这看起来(经过一些研究后)确实是一个Windows问题,所以我和那里的同事认为这可能是寻找帮助的更合适的地方.

我写了一个简短的程序,要么在Windows性能计数器上旋转直到33ms,要么调用Sleep(33).前者没有表现出意想不到的效果,但后者似乎(不一致地)使后续处理减慢了大约40ms(或者说,或者对性能计数器返回的值有一定影响).在旋转或Sleep()之后,程序调用一个例程runInPlace(),它旋转2ms,计算它查询性能计数器的次数,并返回该数字.

当通过旋转完成最初的33ms延迟时,runInPlace()的迭代次数往往是(在我的Windows 10上,XPS-8700)大约250,000.它可能由于其他系统开销而变化,但它变化平滑约250,000.

现在,当通过调用Sleep()完成初始延迟时,会发生一些奇怪的事情.很多对runInPlace()的调用都会返回一个接近250,000的数字,但是其中相当一部分返回的数字接近50,000.同样,范围变化大约50,000,相当顺利.但是,它显然平均了一个或另一个,几乎没有返回80,000到150,000之间的任何回报.如果我在每次延迟后调用runInPlace()100次,而不是只调用一次,那么在20次调用之后,它永远不会在较小的范围内返回多次迭代.由于runInPlace()运行2ms,这意味着我观察到的行为在40ms后消失.如果我运行runInPlace()运行4ms而不是2ms,它在第10次调用之后永远不会返回较小范围内的迭代次数,因此,再次,行为在40ms后消失(同样如果runInPlace()运行仅1ms;在第40次通话后,行为消失了).

这是我的代码:

#include "stdafx.h"
#include "Windows.h"

int runInPlace(int msDelay)
{
    LARGE_INTEGER t0, t1;
    int n = 0;

    QueryPerformanceCounter(&t0);

    do
    {
            QueryPerformanceCounter(&t1);
            n++;
    } while (t1.QuadPart - t0.QuadPart < msDelay);

    return n;
}

int _tmain(int argc, _TCHAR* argv[])
{
    LARGE_INTEGER t0, t1;
    LARGE_INTEGER frequency;
    int n;

    QueryPerformanceFrequency(&frequency);

    int msDelay = 2 * frequency.QuadPart / 1000;

    int spinDelay = 33 * frequency.QuadPart / 1000;

    for (int i = 0; i < 100; i++)
    {
        if (argc > 1) …
Run Code Online (Sandbox Code Playgroud)

c++ windows performance sleep

5
推荐指数
2
解决办法
277
查看次数

为什么"this"会在具有多个基类的类的父类中发生变化?

(初步说明:这个问题与删除void指针是否安全的问题不同,尽管该问题与Update 2中发现的问题有一定关系.这里的问题是基类获得不同值的原因from this是由相同对象的派生类获得的.如果派生对象将调用基类的自杀方法,则基类必须具有虚拟析构函数,并且要删除的指针必须是指针类型-base类;将其存储在void*中不是从基类方法中删除对象的安全方法.)

我有一个钻石形状的多重继承,其中我的子类有两个父母,它们都继承自同一个祖父,因此:

class Grand
class Mom : public virtual Grand
class Dad : public Grand
class Child : Mom, Dad
Run Code Online (Sandbox Code Playgroud)

我写的MomChild,但GrandDad是库类我没有写(这就是为什么Mom从几乎继承Grand,但Dad没有).

Mom实现一个声明的纯虚方法Grand.Dad才不是.因此,Child也实现了相同的方法(因为否则编译器会反对Dad该方法的声明,继承者Child,没有实现).Child的实现只是调用Mom实现.下面的代码(我已经包括了代码DadGrand,因为这是一个SSCCE,不是我坚持使用依赖于库类我没有写的代码):

class Grand
{
public:
    virtual void WhoAmI(void) = 0;
};

class Mom : public virtual Grand
{
public:
    virtual void …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance multiple-inheritance visual-studio-2015

5
推荐指数
1
解决办法
407
查看次数

为什么自动对象的析构函数被调用两次?

(我的问题的答案涉及复制构造函数,但复制发生在从函数返回时,而不是在对另一个类的方法调用中.我实际上看到引用的可能重复,但没有从vector :: copy制作的副本中推断出来:) push_back我的函数在这里也复制了.也许我应该有.)

我试图了解自动对象的构造/破坏.我遇到了一些看起来很可疑的代码,所以我编写了自己的版本以努力理解它.简而言之,原始代码包含一个返回函数本地对象的函数(自动).这对我来说看起来不安全,所以我写了这个程序来探索它:

#include <stdio.h>

class Phantom
{
private:
    static int counter;
    int id;

public:
    Phantom()
    {
        ++counter;
        id = counter;
        printf("Phantom %d constructed.\n", id);
    };

    virtual ~Phantom()
    {
        printf("Phantom %d destructed.\n", id);
    };

    void speak()
    {
        printf("Phantom %d speaks.\n", id);
    };
};

int Phantom::counter = 0;

Phantom getPhantom()
{
    Phantom autoPhantom;

    return autoPhantom; // THIS CAN'T BE SAFE
}

int main()
{
    Phantom phantom;

    phantom = getPhantom();

    phantom.speak();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

Phantom 1 constructed.
Phantom 2 …

c++ destructor automatic-storage

3
推荐指数
2
解决办法
527
查看次数