3
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++コンパイラがコードを検出して最適化できるので、動的バインディング処理はまったくできません。コンパイラは動的バインディングをどの程度静的に変更しますか?
はい、[時々](https://godbolt.org/g/8ksE9t)はそうです。 :-) – WhiZTiM
はい、確かです。コンパイラはコンパイル時に動的型を知ることができ、派生クラスのメンバへの呼び出しを発行します。ただし、コードでは基本クラス型への参照が使用されます。 – IInspectable