class Port
{
private:
char * brand;
char style[20]; // i.e., tawny, ruby, vintage
int bottles;
public:
Port(const char * br = "none", const char * st = "none", int b = 0);
Port(const Port & p); // copy constructor
virtual ~Port() {delete[] brand; }
Port & operator=(const Port & p);
Port & operator+=(int b); // adds b to bottles
Port & operator-=(int b); // subtracts b from bottles, if
int BottleCount() const { return bottles; }
virtual void Show() const;
friend ostream & operator<<(ostream & os, const Port & p);
};
class VintagePort : public Port // style necessarily = "vintage"
{
private:
char * nickname; // i.e., "The Noble" or "Old Velvet", etc.
int year; // vintage year
public:
VintagePort();
VintagePort(const char * br, const char *st, int b, const char * nn, int y);
VintagePort(const VintagePort & vp);
~VintagePort() { delete[]nickname;}
VintagePort & operator=(const VintagePort & vp);
virtual void Show() const;
friend ostream & operator<<(ostream & os, const VintagePort & vp);
};我必须解释为什么operator=()和operator<<()不是虚拟的。我认为operator<<()不能是虚的,因为只有类方法可以是虚的,但我对operator=()一无所知。基类中的指针如何知道它必须使用哪一个operator=()?
第二个问题是关于如何让operator<<()像虚拟方法一样工作,例如:
basicClass B;
inheritClass I;
basicClass *ptr;
ptr=&I;
std::cout << ptr // Here I'd like to use operator<<(std::ostream, inheritClass) 发布于 2015-06-08 08:47:02
operator =不是虚拟的,因为它未标记为virtual。operator =的声明如下所示
//No virtual here
Port& operator =(const Port&);但是,如果operator =是虚拟的,它将被这样声明
virtual Port& operator =(const Port&);
^^^^^^^ Virtual here!因为operator =不是虚拟的,所以编译器在编译时使用静态链接。这意味着被调用的函数依赖于它所引用的变量的类型。考虑下面的代码:
VintagePort vp;
//Calls VintagePort::operator =(const VintagePort&)
vp = VintagePort();
Port* p = &vp;
//Calls Port::operator =(const Port&)
*p = Port();VintagePort::operator =在作为VintagePort访问时调用,而Port::operator =在作为Port访问时调用。(实时示例here。)
要使operator <<的行为如同它是虚拟的一样,您必须在执行打印的类中声明一个虚拟成员函数。像这样的东西
//Inside Port
virtual void Print(std::ostream& os) const
{
os << brand << ' ' << style << ' ' << bottles;
}然后,在每个从Port派生的类(如VintagePort)中,您将覆盖该方法以同时打印该派生类的值。因此,对于VintagePort,您可以这样做
//Inside VintagePort
void Print(std::ostream& os) const
{
//Make Port print first
Port::Print(os);
os << ' ' << nickname << ' ' << year;
}然后,在operator <<中,您所要做的就是对参数调用Print方法。它看起来像这样:
std::ostream& operator <<(std::ostream& os, const Port& p)
{
P.Print();
return os;
}另外,您不必为每个派生类重载operator <<,因为重载只需要Port类中的虚函数。
发布于 2015-06-08 04:58:49
这给人一种codereview的感觉,这不是它的用途--但不管怎样:
std::string:class Port { private: std::string品牌;std::string style;//即tawny,ruby,vintage //... };
此外,一般来说,不要在对象合适的地方使用指针。如果您需要指针,请使用智能指针来清楚地表达其目的。
virtual的latter).
operator<<,因为它不是类成员。这是一个独立的函数,因为它是一个朋友,可以访问您的波特酒类的私有成员。但是你可以在类的外部重载它。这就是通过将不同的重载设置为operator<<(ostream & os, const Port & p);和operator<<(ostream & os, const VintagePort & p);.来直接执行的操作
https://stackoverflow.com/questions/30697903
复制相似问题