class base
{
public:
std::string name() { return basename; }
virtual void print(std::ostream &os) { os << basename; }
private:
std::string basename = "base\n";
};
class derived : public base
{
public:
void print(std::ostream &os) override { base::print(os); os << " derived\n " << i; }
private:
int i;
};
int main()
{
// ex15.14
base bobj;
base *bp1 = &bobj;
base &br1 = bobj;
derived dobj;
base *bp2 = &dobj;
base &br2 = dobj;
// a. this is an object, so compile time.
//bobj.print(std::cout);
// b. this is an object, so compile time.
//dobj.print(std::cout);
// c. function name is not virtual , so no dynamic
// binding happens.so compile time
//std::cout << bp1->name();
// d. function name is not virtual , so no dynamic
// binding happens.so compile time
//std::cout << bp2->name();
// e. run time
//br1.print(std::cout);
// f. run time
//br2.print(std::cout);
return 0;
}
注意e和f,br1和br2是对基类对象bobj和派生类对象dobj的引用。一个好的c ++编译器可以为此检测和优化代码,因此根本没有动态绑定过程吗?
答案 0 :(得分:5)
是。如果编译器可以静态地证明虚方法调用总是针对相同类型的对象(有时它可以),则允许优化调用以不使用调度向量,而是静态绑定到实际实现。
此分析通常是指针分析的简单,上下文不敏感,流不敏感的变体,可由编译器高效运行。它自然不会检测到所有可能的优化点,但是很有可能会遇到明显的优化点。
这是一种有效编译始终使用动态分派的语言的重要技术,如Java。