2015-05-04 56 views
3

真的不好冠軍,想不起怎麼說吧,對不起。C++繼承,調用給定的類函數而不是它的父類?

所以說我有下面的代碼:

class A { 
    virtual int getSize() { 
     return 0; 
    } 
} 

class B : public A { 
    int getSize() { 
     return 32; 
    } 
} 

void doStuff(A a) { 
    std::cout << a.getSize() << std::endl; 
} 

int main() { 
    B b; 
    doStuff(b); 
} 

這將打印出0,但是我希望它打印出來32。換句話說,我想通過它的類,它打印出類功能,所以我可以創建一個類C,其中大小爲64,如果我將該實例傳遞給doStuff函數,我希望它打印64.

有什麼辦法可以在C++中做到這一點,我必須使用模板或我不知道的一些奇特的C++功能嗎?

回答

8

一個字節大小的補丁:

void doStuff(A &a) { 
    std::cout << a.getSize() << std::endl; 
} 

你的版本由值採用的說法,這意味着該功能使得b副本(複印件這是一個A),然後調用複製的getSize()。在這個版本中,函數採用引用的參數,並且調用b自己的getSize(),這是B::getSize()

+2

實現以供將來參考,這種效應被稱爲對象的「切片」。 + 1 – Shaggi

0

將對象切片是一種方法,另外我認爲您要求我認爲C++中多態性的使用非常簡單。 http://www.cplusplus.com/doc/tutorial/polymorphism/

這幾乎立即適用,只需調用您的A級形狀,B和C可以是正方形和三角形。你的DoStuff函數可以帶一個指向Shape的指針,然後你可以將它傳遞給一個三角形或一個正方形,並且當你在函數中引用Shape時,它將調用正確的函數。

所以你得(你也需要讓會員公開,我認爲):

class A { 
public: 
    virtual int getSize() { 
     return 0; 
    } 
}; 

class B : public A { 

public: 
    int getSize() { 
     return 32; 
    } 
}; 

void doStuff(A* a) { 
    std::cout << a->getSize() << std::endl; 
} 

int main() { 
    B b; 
    doStuff(&b); 
} 
1

你應該使用指針,甚至更好:智能指針!這樣,運行時類型的函數就會被調用。這是多態主義的一個基本例子。如果你想避免指針,Beta的切片方法同樣有效。

#include <iostream> 
#include <memory> 

class A { 
    virtual int getSize() { 
     return 0; 
    } 
} 

class B : public A { 
    virtual int getSize() { 
     return 32; 
    } 
} 

void doStuff(std::shared_ptr<A> a) { 
    std::cout << a->getSize() << std::endl; 
} 

int main() { 
    std::shared_ptr<A> b(new B()); 
    doStuff(b); // Will output '32'. 
} 

這應該正確地調用該函數由B.