2012-07-20 64 views
0

我有2个类,基类是“端口”,派生类是“VintagePort”。 据我所知如果我使用引用或基类指针派生类的对象,它会自动找到正确的方法,而不是引用或指针,但完全对象(如果方法是虚拟的)。C++:朋友函数,派生类

在我的情况下,你可以看到两个班级都有朋友功能“操作员< <”。但它看起来像当我使用基类的指针时,它只从基类调用函数。如果我使用“cout < < VintagePort”它工作正常。 我的问题:它工作正常,或者我应该修复代码中的东西?

std::ostream& operator<<(std::ostream& os, const Port& p) 
{ 
os << p.brand << ", " << p.style << ", " << p.bottles << endl; 
return os; 
} 

std::ostream& operator<<(std::ostream& os, const VintagePort& vp) 
{ 
os << (const Port &) vp; 
cout << ", " << vp.nickname << ", " << vp.year << endl; 
return os; 
} 




VintagePort vp1; 
VintagePort vp2("Gallo", "lekko brazowy", 50, "Blaze", 1990); 
VintagePort vp3(vp2); 

Port* arr[3]; 
arr[0] = &vp1; 
arr[1] = &vp2; 
arr[2] = &vp3; 

for (int i = 0; i < 3; i++) 
{ 
    cout << ">>>>> " << i+1 << " <<<<<" << endl; 
    cout << *arr[i]; // call for base class instead derived class 
    arr[i]->Show();  
} 
+0

我觉得程序工作正常这是执行功能'的std :: ostream的和运营商<<(STD :: ostream&os,const Port&p)' 因为你传递的参数确实是一个指向'Port'的指针,而不是'VintagePort',所以它调用函数匹配参数列表。在这个例子中继承并不重要,因为<<运算符的重载,即使是朋友,也不是该类的成员。 – jlledom 2012-07-20 11:50:12

回答

5

编译器现在不会将指针实际指向继承类。解决此问题的一种方法是在基类中为输出提供虚函数,并在继承基类的类中覆盖它。然后在输出操作符中调用这个虚拟方法。

0

在C++中,多态只能通过虚函数实现,并且operator<<不是一个(因为第一个参数是std::ostream,所以不能用于你的目的)如果你需要这种行为,简单的方法是提供层次结构中的虚拟打印功能,并具备operator<<转发调用执行动态调度。

struct base { // Don't forget virtual destructors 
    virtual void print(std::ostream&) const; 
}; 
struct derived : base { 
    virtual void print(std::ostream&) const; 
}; 
std::ostream& operator<<(std::ostream& o, const base& b) { 
    b.print(o); 
    return o; 
}