[英]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.