簡體   English   中英

多態性與引用成員變量

[英]polymorphism with reference member variable

有人能告訴我下面的程序有什么問題嗎? 我在類中使用引用成員變量進行多態。 我期待第二個cout說“derived2”,但它說“base”;

#include <iostream>

// Example program
#include <iostream>
#include <string>
class base
{
public:
    virtual void print(){ std::cout<<"base"<<std::endl;}
};
class derived: public base
{
public:
    virtual void print(){ std::cout<<"derived"<<std::endl;}
};

class derived2: public base
{
    virtual void print(){ std::cout<<"derived2"<<std::endl;}
};

class foo
{
public:
    base & bar;
    base boo;
    derived foobar;
    derived2 foobar2;
    foo(): bar(boo){}
    void newfoo(base & newfoo){ bar = newfoo; bar.print();}
};
int main()
{
  foo test;
  test.bar.print();
  test.newfoo(test.foobar2);
}

輸出:基礎

如其他人所述,您無法重新分配參考。
每當你執行bar = newfoo你都不會重置引用。 而是使用newfoo作為參數調用operator= for bar
因此,在您的情況下,您正在切割對象並(讓我說)在bar復制其base部分。


可以重新分配的一種類似引用的工具存在於標准模板庫中,它被稱為std::reference_wrapper
它遵循一個基於您的代碼的示例,它使用它並具有預期的行為:

#include<functional>
#include <iostream>
#include <string>

class base
{
public:
    virtual void print() { std::cout<<"base"<<std::endl;}
};
class derived: public base
{
public:
    virtual void print(){ std::cout<<"derived"<<std::endl;}
};

class derived2: public base
{
    virtual void print(){ std::cout<<"derived2"<<std::endl;}
};

class foo
{
public:
    std::reference_wrapper<base> bar;
    base boo;
    derived foobar;
    derived2 foobar2;
    foo(): bar(boo){}
    void newfoo(base & newfoo){ bar = newfoo; bar.get().print();}
};
int main()
{
  foo test;
  test.bar.get().print();
  test.newfoo(test.foobar2);
}

在這種情況下, operator=實際重新綁定對給定對象的引用。 無論如何,正如您所看到的,在這種情況下,您必須調用get來訪問基礎引用。

注意:拋開上面的示例,您的代碼不是std::reference_wrapper的典型用例。
我只是為了完整而提到它。

您無法“重新分配”參考。 當賦值運算符與引用一起使用時,它會分配基礎值。

因此, bar = newfoo; 簡單地將base類型的foo賦予foobar ,在此過程中對其進行切片。

如果您使用指針替換引用,則可能會有不同的行為,可以重新分配。

bar是對boo的引用,無論你賦予它什么, boo都是base類型。

賦值只能更改變量值,而不能更改其類型。

多態性不適用於參考文獻。 嘗試這個:

#include <iostream>

// Example program
#include <iostream>
#include <string>
class base
{
public:
   virtual void print(){ std::cout << "base" << std::endl; }
};
class derived : public base
{
public:
   virtual void print(){ std::cout << "derived" << std::endl; }
};

class derived2 : public base
{
   virtual void print(){ std::cout << "derived2" << std::endl; }
};

class foo
{
public:
   base* bar; 
   foo(): bar(0) {}
   void newfoo(base* newfoo){ bar = newfoo; bar->print(); }
};

int main() {
   foo test;
   test.newfoo(new derived2);
}

暫無
暫無

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

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