2012-11-04 94 views
1

這是我的代碼C++錯誤沒有匹配的功能

#include <iostream> 
#include <vector> 
#include <memory> 
#include <tr1/memory> 
using namespace std; 

class Animal { 
    public: 
    string name; 
    Animal (const std::string& givenName) : name(givenName) { 

    } 

    }; 

class Dog: public Animal { 
    public: 
    Dog (const std::string& givenName) : Animal (givenName) { 

    } 
    string speak() 
     { return "Woof, woof!"; } 
    }; 

class Cat: public Animal { 
    public: 
    Cat (const std::string& givenName) : Animal (givenName) { 
    } 
    string speak() 
     { return "Meow..."; } 
    }; 

int main() { 
    vector<Animal> animals; 
    Dog * skip = new Dog("Skip"); 
    animals.push_back(skip); 
    animals.push_back(new Cat("Snowball")); 

    for(int i = 0; i< animals.size(); ++i) { 
     cout << animals[i]->name << " says: " << animals[i]->speak() << endl; 
    } 

} 

這些都是我的錯誤:

index.cpp: In function ‘int main()’: 
index.cpp:36: error: no matching function for call to ‘std::vector<Animal, std::allocator<Animal> >::push_back(Dog*&)’ 
/usr/include/c++/4.2.1/bits/stl_vector.h:600: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Animal, _Alloc = std::allocator<Animal>] 
index.cpp:37: error: no matching function for call to ‘std::vector<Animal, std::allocator<Animal> >::push_back(Cat*)’ 
/usr/include/c++/4.2.1/bits/stl_vector.h:600: note: candidates are: void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Animal, _Alloc = std::allocator<Animal>] 
index.cpp:40: error: base operand of ‘->’ has non-pointer type ‘Animal’ 
index.cpp:40: error: base operand of ‘->’ has non-pointer type ‘Animal’ 

我想要做什麼:

我只想用一個動態的數據結構這將通過可能的動物對象的列表。

我想在C++語法中學習這種多態概念。

我對Java和PHP很熟悉,但對C++來說卻少得多。

更新:

我已經添加了其中一個答案中提到的更改。 http://pastebin.com/9anijwzQ

但我得到有關unique_ptr的錯誤。我已經包含了內存。所以我不確定問題是什麼。

http://pastebin.com/wP6vEVn6是錯誤消息。

回答

3

有兩個問題。首先,您的向量包含Animal對象,並且您正試圖用指向Animal派生類型的指針填充它。 AnimalAnimal*不是相同的類型,所以操作通常不會編譯。

二,Animal沒有方法speak()。如果您要將派生類型Animal插入向量中,您將獲得object slicing。你可以通過讓你的向量保持智能指針Animal來避免它,例如std::vector<std::unique_ptr<Animal>>。但你仍然需要給虛擬方法Animal一個speak()。例如:

class Animal { 
public: 
    std::string name; 
    Animal (const std::string& givenName) : name(givenName) {} 
    virtual std::string speak() = 0; 
    virtual ~Animal() {} 
}; 

int main() { 
    std::vector<std::unique_ptr<Animal>> animals; 
    animals.push_back(std::unique_ptr<Animal>(new Dog("Skip"))); 
    animals.push_back(std::unique_ptr<Animal>(new Cat("Snowball"))); 
} 

我在哪裏都取得Animal::speak()一個純虛方法和給定Animal虛析構函數。

請參閱when to use virtual destructorswhen should a virtual method be pure

+0

我已經添加了所提及的更改。 http://pastebin.com/9anijwzQ但我得到有關unique_ptr的錯誤。但我已經包含了內存。所以我不確定問題是什麼。 http://pastebin.com/wP6vEVn6是錯誤消息。 –

+0

@kimsia我添加了一個例子。 – juanchopanza

+0

謝謝,我幫你解決了這個問題。我想問幾個問題來澄清。我理解需要將std :: string speak()作爲虛擬方法。我不明白你爲什麼讓它= 0; 其次,我不確定虛擬的目的是什麼〜Animal(){} –

2

如果您想推Animal*skip,則應聲明您的vectorvector<Animal*>。而且你確實需要指針才能使用多態。此外,你的基類動物也需要一個speak()方法 - 否則你不能在你編譯時只知道是Animal的對象上調用它。它應該像你期望的一樣,一旦這些改變已經完成了。

相關問題