虚拟功能
我有一个关于 C++ 虚函数的问题。
派生类 (DerivedAlgo
) 实现了虚函数 (BaseAlgo::process
),但通过使用 DerivedData
对函数签名进行了一些更改type 作为输入参数而不是 BaseData。
尽管基类中有纯抽象函数,我仍然能够创建 DerivedAlgo 类的实例,并且编译器根本不会抱怨。
我只是想知道有人知道任何可以解释以下代码的 C++ 规则。
class BaseData{};
class DerivedData: public BaseData{};
class BaseAlgo{
public:
virtual void process(BaseData& data) = 0;
};
class DerivedAlgo: BaseAlgo{
public:
virtual void process(DerivedData& data){
std::cout << "hello world!" << std::endl;
}
};
在我的另一个示例代码中,我定义了 process(DerivedData&)
和 process(BaseData&)
。
编译器仍然可以运行,不会出现任何歧义。
class DerivedAlgo{
public:
virtual void process(DerivedData& data){...}
virtual void process(BaseData& data){...}
};
BaseData baseData;
DerivedData derivedData;
derivedAlgo.process(baseData);
derivedAlgo.process(derivedData);
我非常感谢您的任何意见。谢谢!
I have a question regarding to the C++ virtual function.
The derived class (DerivedAlgo
) implements the virtual function (BaseAlgo::process
) but changes a little bit in the function signature by using the DerivedData
type as the input parameter instead of BaseData.
Despite the pure abstract function in the base class, I am still able to create an instance of the DerivedAlgo
class and the compiler does not complain at all.
I just wonder anyone knows any C++ rule which can explain the following code.
class BaseData{};
class DerivedData: public BaseData{};
class BaseAlgo{
public:
virtual void process(BaseData& data) = 0;
};
class DerivedAlgo: BaseAlgo{
public:
virtual void process(DerivedData& data){
std::cout << "hello world!" << std::endl;
}
};
In my another sample code, I define process(DerivedData&)
and process(BaseData&)
.
The compiler can still run through without complaining any ambiguity.
class DerivedAlgo{
public:
virtual void process(DerivedData& data){...}
virtual void process(BaseData& data){...}
};
BaseData baseData;
DerivedData derivedData;
derivedAlgo.process(baseData);
derivedAlgo.process(derivedData);
I really appreciate any of your inputs. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的第一个示例无法在 g++ 4.2 上编译。作为参考,我这样做了:
并得到了这个:
如果像我的示例确实编译了,那么你几乎肯定有一个有错误的编译器。
您的第二个示例将编译,因为它覆盖了抽象函数。第一个调用将调用基础数据版本,而第二个调用将调用流程的派生版本。
请注意,在第一个示例中,您隐藏了函数的
process(base)
版本,而不是完全覆盖它。重写虚拟函数时不应更改函数签名。Your first example doesn't compile on g++ 4.2. For reference I did this:
And got this:
If something like my example did compile then you almost surely have a buggy compiler.
Your second example will compile because it overrides the abstract function. The first call will call the base data version while the second call will call the derived version of process.
Note that in your first example you're hiding the
process(base)
version of the function, not overriding it at all. You shouldn't change the function signature when overriding virtual functions.您确定没有收到编译器错误吗?
当我编译这个(在 MSVC9 中)时:
我收到预期的错误:
这是因为你无法使用不同的参数列表覆盖虚拟:
10.3 虚拟函数
在派生类中声明重写时唯一的余地是使用协变返回类型。
如果您从未真正调用派生类,则编译器可能没有彻底检查您的代码。
Are you sure you're not getting a compiler error?
When I compile this (in MSVC9):
I get the expected error:
This is because you cannot override virtuals with different parameter lists:
10.3 Virtual Functions
The only leeway you have in declaring overrides in the derived class is with covariant return types.
It's possible your compiler didn't thoroughly check your code if you never actually call the derived class.
你遇到的问题是c++不支持双重调度。您需要在 BaseAlgo 类上使用 访问者模式。
the problem you have is that c++ does not support double dispatch. You need to use a Visitor pattern on your BaseAlgo class.