C++:编译对无关派生类、bug或特性的函数调用
C++: compiling function call to unrelated derived class, bug or feature?
在C++中闲逛时,我偶然发现了一些我认为是clang++(6.0(和g++(5.3(错误的东西:我能够欺骗编译器调用它不应该调用的函数。
简而言之,我声明了一个抽象基类,从中派生出两个类:非抽象类和抽象类,它们仅通过它们的公共基类相关,但具有不同的功能。实例化非抽象基类,并诱使编译器创建一个指向非派生类的抽象派生类指针,我可以通过该指针调用原始非抽象类和抽象类的函数。
最简单的例子是,让我头疼的两行在底部,中间有一条带星号的评论行:
#include <cassert>
#include <iostream>
#include <typeinfo>
class MYBase {
public:
virtual void fun1() = 0;
};
class MYDer1 : public MYBase {
public:
~MYDer1() { std::cout << "~MYDer1()n"; }
void fun1() { std::cout << "MYDer1 fun1n"; }
};
class MYDer2 : public MYBase {
public:
~MYDer2() { std::cout << "~MYDer2()n"; }
void something2() { std::cout << "MYDer2 something2n"; }
};
int main () {
MYDer1 x1;
// Good: cannot instantiate a 'MYDer2' as it is an abstract class
// due to unimplemented pure virtual method 'fun1' in 'MYDer2'
//
// MYDer2 x2;
// Good, clang++ and g++ rightfully refuse to compile this:
//
// auto * pd2 = static_cast<MYDer2 *>(&x1);
// So let's be 'clever' and take a detour via 'void':
auto * pd2 = static_cast<MYDer2 *>(static_cast<void *>(&x1));
// Just to be sure the compiler got it right
assert(typeid(pd2) == typeid(MYDer2 *));
/***********************************************************/
// There is no "fun1" declared in MYDer2
// So why does this even compile?
pd2->fun1();
// And why does this execute correctly?
pd2->something2();
return 0;
}
我错过了什么?
这是一种未定义的行为,所以这次你射中了自己的腿,但没有打中。程序员有责任确保被取消引用的指针真正指向指定类型的对象。
这是未定义的行为,因为x1
的类型为MYDer1
,并且您强制将其强制转换为MYDer2
。代码可能不起作用,因为您并没有真正使用函数something2
执行任何操作。尝试向MYDer2
添加一个成员变量并打印它以查看问题。
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- C++:编译对无关派生类、bug或特性的函数调用