gpt4 book ai didi

C++ - 方法覆盖未按预期表达

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

我有一个基类Point(表示空间中的二维点),它对于移动操作是非线程安全的;所以我定义了一个继承类 LockedPoint,它覆盖了基类中的两个方法:moveTomoveBy:

void Point::moveTo(float xPos, float yPos) {
x = xPos;
y = yPos;
}

void Point::moveBy(float xOff, float yOff) {
x += xOff;
y += yOff;
}

void LockedPoint::moveTo(float xPos, float yPos) {
MutGuard m(lock);
x = xPos;
y = yPos;
}

void LockedPoint::moveBy(float xOff, float yOff) {
MutGuard m(lock);
x += xOff;
y += yOff;
}

( where x and y = private member variables,
lock = a private mutex, and
MutGuard = typedef lock_guard<mutex> )

为了直观地看到“未锁定”Point 的问题,我编写了一个测试例程:

void sleepForMS(long ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

void messWithPoint(Point& p, int type) {

float n = 1;
if (type) n *= -1;

for (long i = 0; i < 10000; i++) {

p.moveBy(n, n);

sleepForMS(rand() % (type ? 2 : 3));

if (i % 500 == 0)
std::cout << i << ":\t" << p << std::endl;

}

}


int main(int argc, char* argv[]) {
using namespace std;

Point p;

thread t1(messWithPoint, std::ref(p), 0);

sleepForMS(33);

thread t2(messWithPoint, std::ref(p), 1);

cout << "Started\n";

t1.join();
t2.join();

cout << p << endl;
}

对于 Point,生成的 p 是“损坏的”,正如预期的那样(到最后它应该等于 (0,0) ,但事实并非如此)。但是,如果我将 p 更改为 LockedPoint,仍会调用 moveBy 的基本版本(通过打印调试验证)。

我阅读了“覆盖”方法(显然更正确地称为“方法隐藏”),据我所知,如果覆盖方法与基本方法具有相同的签名,它会隐藏基本版本,并被称为反而。尽管 2 具有相同的签名,但为什么要调用基本方法?我唯一能想到的是,因为我在 messWithPoint 的参数列表中指定了 Point,所以它按字面意思调用 Point'版本。如果我将签名更改为 void messWithPoint(LockedPoint& p, int type),则生成的 LockedPoint(0,0),正如预期的那样。它不应该“看到”传递的 LockedPoint 覆盖使用的方法,并使用“最少隐藏”的版本吗?

如果这不是它的工作方式,是否有一种方法可以指定采用基类,但让它使用任何可用的覆盖版本?

最佳答案

成员函数不是虚函数,因此使用编译时已知的类中的函数。

但是,对于像点这样的简单类,使用虚成员函数或提供自动互斥与 C++ 不为不用的东西付费的理念背道而驰。

只需复制点。

关于C++ - 方法覆盖未按预期表达,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29126302/

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