有人可以告诉我下面的程序有什么问题吗?我在类中使用引用成员变量进行多态。我期待第二个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);
}
输出: 基础 基
答案 0 :(得分:2)
如其他人所述,您无法重新分配参考文献
每当您执行bar = newfoo
之类的操作时,您都不会重置参考。相反,您使用operator=
作为参数调用bar
newfoo
因此,在您的情况下,您正在切割您的对象,并(让我说)在base
中复制其bar
部分。
标准模板库中存在一种可以重新分配的类似参考工具,它名为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
的典型用例。
我只是为了完整而提到它。
答案 1 :(得分:1)
您无法“重新分配”参考。当赋值运算符与引用一起使用时,它会分配基础值。
因此,bar = newfoo;
只是将foo
类型的base
分配给foobar
,并在此过程中对其进行切片。
如果您使用指针替换引用,则可能会有不同的行为,可以重新分配。
答案 2 :(得分:0)
bar
是对boo
的引用,boo
的类型为base
,无论您分配给它。
分配只能更改变量值,而不能更改其类型。
答案 3 :(得分:0)
多态性不适用于参考文献。试试这个:
#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);
}