2013-08-23 61 views
1

我目前正在學習動態綁定和虛函數。這來自Accelerated C++,第13章:在編譯時如何識別對象類型?

[...]我們想在運行時做出這個決定。也就是說,我們希望 系統根據傳遞給該函數的實際類型來運行正確的函數,該函數僅在運行時已知。

我不明白在編譯時對象的類型可能未知的想法。源代碼不明顯嗎?

回答

1

根本不是。考慮下面這個例子:

struct A { 
    virtual void f() = 0; 
}; 

struct B : A { 
    virtual void f() { std::cerr << "In B::f()\n"; } 
}; 

struct C : A { 
    virtual void f() { std::cerr << "In C::f()\n"; } 
}; 

static void f(A &a) 
{ 
    a.f(); // How do we know which function to call at compile time? 
} 

int main(int,char**) 
{ 
    B b; 
    C c; 
    f(b); 
    f(c); 
} 

當全局函數f編譯,也沒有辦法知道哪些功能應該調用。實際上,每次都需要調用不同的函數。第一次調用f(b)時,需要調用B::f(),第二次調用f(c)時,需要調用C::f()

1

C++有一個指針的概念,其中變量僅包含對實際對象的「句柄」。實際對象的類型在編譯時不知道,只在運行時才知道。例如:

#include <iostream> 
#include <memory> 

class Greeter { 
public: 
    virtual void greet() = 0; 
}; 

class HelloWorld : public Greeter { 
public: 
    void greet() {std::cout << "Hello, world!\n";} 
}; 

class GoodbyeWorld : public Greeter { 
public: 
    void greet() {std::cout << "Goodbye, world!\n";} 
}; 

int main() { 
    std::unique_ptr<Greeter> greeter(new HelloWorld); 
    greeter->greet(); // prints "Hello, world!" 
    greeter.reset(new GoodbyeWorld); 
    greeter->greet(); // prints "Goodbye, world!" 
} 

參見:沃恩卡託的答案,它採用引用(這是另一種方式來保存的句柄對象)。

0

假設你有一個指向基類指向派生類對象

Base *pBase = new Derived; 

// During compilation time, compiler looks for the method CallMe() in base class 
// if defined in class Base, compiler is happy, no error 
// But when you run it, the method call gets dynamically mapped to Derived::CallMe() 

// ** provided CallMe() is virtual method in Base and derived class overrides it. 

pBase->CallMe(); // the actual object type is known only during run-time. 
+0

那很可能是_方式_的OP的水平之上,鑑於問題的任擇議定書的要求。 –

+0

儘管如此,我的例子比你的更簡單,但仍然有效地傳達了它:) – Arun

相關問題