簡體   English   中英

繼承類的意外轉換

[英]Unexpected conversion of inherited classes

我正試圖制作一種“收藏品”。 此類需要接受從基類繼承的所有類。

例如:

想象一下,我們有一個名為“A”的基類,我們還有許多繼承自這個類“A”的其他類。 所以我們有,繼承自“A”的類“B”,繼承自“A”的類“C”,依此類推,我們有一個名為“collection”的類,它也繼承自“A”。 類“collection”有一個“std :: map”,其中使用“add”方法保存所有類,並可以使用“get”進行檢索。

發生的事情是它以某種方式工作,但應用程序轉換為“基類”而不是返回傳遞的類。

讓我們轉到代碼(請參閱有關代碼的注釋以了解輸出):

這是工作代碼:

#include <iostream>
#include <string>
#include <map>

class A
{
public:
    virtual void saySomething()
    {
        std::cout << "Hello from A object" << std::endl;
    }
};

class B : public A
{
public:
    void saySomething()
    {
        std::cout << "Hello from B object" << std::endl;
    }
};

class C : public A
{
    void saySomething()
    {
        std::cout << "Hello from C object" << std::endl;
    }
};

class Collection : public A
{
public:
    void add(const std::string & key, A * value)
    {
        storage[key] = value;
    }
    A * get(const std::string & key)
    {
        return storage[key];
    }
private:
    std::map<std::string, A *> storage;
};

int main( int argc, char ** argv )
{

    B * b = new B;
    C * c = new C;
    Collection * col = new Collection;
    Collection * col2 = new Collection;
    col->add("b", b); // works, because "b" inherits from "A" class.
    col->add("c", c); // works, because "c" inherits from "A" class.
    col->add("col2", col2); // watch this part...
    col->get("b")->saySomething(); // works - Output: Hello from B object
    col->get("c")->saySomething(); // works - Output: Hello from C object
    return 0;

}

它工作,但當我嘗試檢索“col2”並使用他的方法...

col->get("col2")->add("b", b);
// output: error: 'class A' has no member named 'add'

如果我沒錯,它需要工作,因為“get”方法返回對象,所以我有“col2”對象的方法對嗎? 如果你回答是,我們有同樣的想法,我不知道發生了什么。 在“b”和“c”對象上它返回對象並且我有“saySomething”方法,但是當我嘗試檢索“col2”時,它將對象作為“A”對象,因此錯誤:

'A類'沒有名為'add'的成員

如果我這樣做會變得更糟:

col->get("col2")->saySomething(); // output: Hello from A object

我們的想法是,一個集合只接受從基類繼承的類,並接受從同一基類繼承的其他集合,如遞歸。

C ++具有靜態類型,因此當您有一個類型為A的對象 - 這就是您的get方法返回的內容 - 只能使用在A聲明的方法。 要調用add上的結果get你要么需要投與static_castdynamic_cast ,或者完全重新考慮你的類層次結構。 為什么Collection需要從A繼承? (並回答你的上一個問題,因為它繼承了,如果你調用saySomething它將調用在A聲明的方法,因為Collection不提供自己的覆蓋)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM