gpt4 book ai didi

c++ - void 方法和 lambda 中的常量正确性 'trick'

转载 作者:行者123 更新时间:2023-11-30 01:15:58 24 4
gpt4 key购买 nike

我有一个方法接受一个对象的引用作为 const,这个方法不会改变方法的任何内容,const 表明,问题是这个方法还调用了类中的其他方法并且是void,不接受任何参数并且也是虚拟的,这意味着扩展基类的类可以覆盖方法但它也需要是常量。例如:

#include <iostream>

class Boz
{
public:
virtual void introduce() const = 0;
};

class Foo
{
public:
virtual void callable() const
{
// ...
}

void caller(const Boz& object) const
{
callable();
object.introduce();
}
};

class Bar : public Boz
{
public:
void introduce() const
{
std::cout << "Hi." << std::endl;
}
};

class Biz : public Foo
{
public:
void callable() const
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};

int main(void)
{
Biz biz;
biz.caller(Bar());

return 0;
}

输出将是:

I'm being called before the introduce.
Hi.

如您所见,callable 必须是 const 才能被调用。如果我改变并这样做:

class Biz : public Foo
{
public:
void callable()
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};

它会编译,不会抛出错误,但不会调用可调用方法,而是调用定义为 const 的虚拟方法。这很明显。

这里最棘手的部分:

class Foo
{
public:
virtual void callable()
{
// ...
}

void caller(const Boz& object) const
{
auto trick = [&] () { callable(); };

trick();

object.introduce();
}
};

class Biz : public Foo
{
public:
void callable()
{
std::cout << "I'm being called before the introduce." << std::endl;
}
};

它起作用了,callable 方法被调用了。没有像 passing 'const ...' as 'this' argument 这样的错误。

我想做的是调用 callable 而无需成为 const 原因很简单:该方法不会改变任何东西,他无权访问该对象begin 作为 caller 方法的参数传递,然后我们假设他不需要成为 const 但即使那样编译器也会抛出错误。真正的问题是 callable 是虚拟的,类可以扩展基类,实现自己的 callable 并尝试调用其他方法,但如果不是 则不能const 也是如此。

我想要的几乎就是知道如何在不需要成为 const 的情况下调用虚拟方法(原因几乎是,我强制用户扩展类并覆盖 callable 方法只调用 const 方法,这不是我想要的),当然要理解 lambda 会发生什么以及它为什么起作用。

最佳答案

带有 lambda 的代码绝对不应该编译,它只是一个 GCC 错误(报告为 PR 60463PR 60755 )现在已在 svn 主干中修复,由 http://gcc.gnu.org/r210292

如果您真的需要从常量函数调用非常量成员函数,您需要放弃常量性:

const_cast<Foo*>(this)->callable();

但这是相当冒险的,至少有两个原因

  1. 如果对象被声明为 const 那么它是未定义的行为,例如常量 Foo f; f.caller(boz); 是未定义的行为。

  2. 你正在调用一个虚函数,你不一定知道派生类的重写绝对不会修改任何东西。虚函数的全部意义在于派生类可以做一些不同的事情,而基类不知道细节。

我会更改您的设计,以便您要调用的虚函数是 const,或者 caller 函数是非常量。其他任何事情都是危险的。

关于c++ - void 方法和 lambda 中的常量正确性 'trick',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27536812/

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