gpt4 book ai didi

c++ - 为什么此代码返回 -nan(ind)?c++

转载 作者:行者123 更新时间:2023-11-30 02:18:33 26 4
gpt4 key购买 nike

我正在尝试编写一个 Scaler 类,该类采用具有分数的子测试。

Scaler 使用其子级分数类的缩放方法来重新缩放其值(例如 1/1 缩放 5 = 5/5 或 0/1 缩放 5 = 0/5)。

但是,每当我使用 DummyTest 类作为子级运行我的代码时,它都会返回一个“-nan(ind)/5 而不是 5/5 和我的 test case fails

TEST_CASE("Scaling test returning 1/1 to 5/5")
{
auto test = std::make_shared<DummyTest>(Score(1, 1)); // Tests that always returns 1/1
Scaler scaler(test, 5);

CHECK(scaler.run() == Score(5, 5));
}

这是我的代码:

class Score {
public:
double value;
double maximum;

Score() : value(0), maximum(0) { }
Score(double maximum) : value(0), maximum(maximum) { }
Score(double value, double maximum) : value(value), maximum(maximum) { }

Score scale(double scale) const;
bool success();
};

Score Score::scale(double scale) const {
double a = (value / maximum) * scale;
double b = scale;
return Score(a , b);
}

class Test {
public:
virtual Score run() const;
};

class DummyTest : public Test {
Score score;

public:
DummyTest(const Score& score) : score(score) { }

Score run() const override {
return score;
}
};

class Scaler : public Test {
public:
Test child;
double maximum;

Scaler(std::shared_ptr<Test> child, double maximum) : child(*child), maximum(maximum) { }

Score run() const override;

};

Score Scaler::run() const {
Score c = child.run().scale(maximum);
return c;
}

最佳答案

您已成为所谓 object slicing 的受害者;为了更好地说明,我稍微简化了代码(无论您是通过智能指针还是原始指针接收指针都没有关系......)

class Scaler
{
Test child;
Scaler(Test* child, double maximum) : child(*child) { }
// here!!!
};

实际发生的是将派生类分配给基类的一个实例。基类(作为值)不能持有派生类的实例,所以属于派生类的所有数据都被“切断”,或者说,只有派生类的基类部分被复制到测试成员中.由于它现在是一个真正的 Test 实例,它将调用 Test::run(),它只返回 Score(),然后您结束向上除以 0...

现在,既然您已经引入了智能指针,那么您可以从中受益:

class Scaler
{
std::shared_ptr<Test> child;
Scaler(std::shared_ptr<Test> const& child, double maximum)
// you don't need the reference counting stuff for the parameter,
// so you can pass as reference
: child(child) // assigning the reference to our member
// (now with reference count management)
{ }
};

更简单的变体是使用原始引用:

class Scaler
{
Test& child;
// ^ (!)
Scaler(Test& child, double maximum)
: child(child), maximum(maximum)
{ }
};

这甚至允许在您的测试函数中使用更简单的代码:

DummyTest test(Score 1,1));
Scaler s(test, 5);

但是请注意,对于原始引用,您需要确保引用测试至少与引用测试一样长(或者至少,只要引用测试仍在使用其引用),否则您遭受未定义的行为。上面的代码片段保证了这一点,但是,如果你这样做的话:

 Scaler s(DummyTest(Score 1,1));
s.run();

现在,从构造函数返回后,DummyTest 实例再次被销毁,您在 s.run() 中有一个悬空引用。

关于c++ - 为什么此代码返回 -nan(ind)?c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52016087/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com