当我尝试通过继承 class 的指针使用重新加载的友元函数时,它使用来自基础 class 的函数
When I am trying to use reloaded friend function by pointer from inherited class, it uses function from base class
我提前为我歪歪扭扭的英语表示歉意(如果有任何明显的错误,我很乐意知道)
我的问题是不能使用继承 class 的重载函数。
我创建了指向 Base class 的指针数组,并且在程序创建对象期间,它可以是 base class 或继承的。在使用重载函数 (operator<<) 时,它不断使用 base class 的选项,但是当我创建两个单独的对象时(Base class, Inherited class from base class), 重载运算符工作得很好。我应该往哪个方向挖?
有代码
#include <iostream>
#include "port.hpp"
using namespace std;
int main()
{
port *p_port[2];
p_port[0] = new VintagePort("BrandONe", 10, "NickName", 19978);
p_port[1] = new port("BrandNameTwo","StyleTwo",1);
for (int i = 0; i < 2; i++)
{
cout << *p_port[i] << endl;
}
for (int i = 0; i < 2; i++)
delete p_port[i];
cout << endl;
port p("BrandNameTwo","Style",2);
VintagePort vp("BrandName",19,"NickName",1982);
cout << p << endl;
cout << vp << endl;
}
#ifndef PORT_HPP_
#define PORT_HPP_
#include <iostream>
class port
{
private:
char *brand;
char style[20];
int bottles;
public:
port(const char *br = "none", const char *st = "none", int b = 0);
port(const port &p);
virtual ~port() { delete[] brand; }
port &operator=(const port &p);
port &operator+=(int b);
port &operator-=(int b);
int BottleCount() const { return bottles; }
virtual void Show() const;
friend std::ostream &operator<<(std::ostream &os, const port &p);
};
class VintagePort : public port
{
private:
char *nickname;
int year;
public:
VintagePort();
VintagePort(const char *br, int b, const char *nn, int y);
VintagePort(const VintagePort &vp);
~VintagePort() { delete[] nickname; }
VintagePort &operator=(const VintagePort &vp);
void Show() const;
friend std::ostream &operator<<(std::ostream &out, const VintagePort &vp);
};
#endif
#include "port.hpp"
using std::ostream;
port::port(const char *br, const char *st, int b)
{
brand = new char[strlen(br) + 1];
strcpy(brand, br);
strcpy(style, st);
bottles = b;
}
port::port(const port &p)
{
brand = new char[strlen(p.brand) + 1];
strcpy(brand, p.brand);
strcpy(style, p.style);
bottles = p.bottles;
}
port &port::operator=(const port &p)
{
if (this == &p)
return *this;
delete[] brand;
brand = new char[strlen(p.brand) + 1];
strcpy(brand, p.brand);
strcpy(style, p.style);
bottles = p.bottles;
return *this;
}
port &port::operator+=(int b)
{
bottles += b;
return *this;
}
port &port::operator-=(int b)
{
bottles -= b;
return *this;
}
void port::Show() const
{
std::cout << "Brand: " << brand;
std::cout << "\nKind: " << style;
std::cout << "\nBottles: " << bottles << std::endl;
}
ostream &operator<<(ostream &out, const port &p)
{
out << p.brand << ", " << p.style << ", "
<< p.bottles << std::endl;
return out;
}
VintagePort::VintagePort()
{
nickname = nullptr;
year = 0;
}
VintagePort::VintagePort(const char *br, int b, const char *nn, int y)
: port(br, "vintage", b)
{
year = y;
nickname = new char[strlen(nn) + 1];
strcpy(nickname, nn);
}
VintagePort::VintagePort(const VintagePort &vp) : port(vp)
{
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
}
VintagePort &VintagePort::operator=(const VintagePort &vp)
{
if (this == &vp)
return *this;
port::operator=(vp);
delete[] nickname;
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
return *this;
}
void VintagePort::Show() const
{
std::cout << "\nNickname: " << nickname << std::endl;
port::Show();
}
ostream &operator<<(ostream &out, const VintagePort &vp)
{
out << vp.nickname << ", ";
// operator<<(os, (const port &)vp);
operator<<(out, (const port &)vp);
return out;
}
这里是程序的结果
BrandONe, vintage, 10
BrandNameTwo, StyleTwo, 1
BrandNameTwo, Style, 2
NickName, BrandName, vintage, 19
我是新来的,抱歉,如果我做错了什么
重载和覆盖是完全不同的事情。
在编译时选择重载,使用静态类型。
由于数组元素的类型是 port*
,因此选择了 port&
重载。
如果您想要一个“动态”operator<<
,请创建一个接受基 class 并仅分派给您可以覆盖的虚拟成员函数的函数。
示例:
class port
{
// ...
public:
virtual std::ostream& print(std::ostream* os) const
{
out << brand << ", " << style << ", "
<< bottles << std::endl;
return out;
}
};
std::ostream& operator<<(std::ostream& os, const port& p)
{
return p.print(os);
}
class VintagePort : public port
{
// ...
public:
std::ostream& print(std::ostream& out) const override
{
out << vp.nickname << ", ";
return port::print(out);
}
};
我提前为我歪歪扭扭的英语表示歉意(如果有任何明显的错误,我很乐意知道) 我的问题是不能使用继承 class 的重载函数。 我创建了指向 Base class 的指针数组,并且在程序创建对象期间,它可以是 base class 或继承的。在使用重载函数 (operator<<) 时,它不断使用 base class 的选项,但是当我创建两个单独的对象时(Base class, Inherited class from base class), 重载运算符工作得很好。我应该往哪个方向挖? 有代码
#include <iostream>
#include "port.hpp"
using namespace std;
int main()
{
port *p_port[2];
p_port[0] = new VintagePort("BrandONe", 10, "NickName", 19978);
p_port[1] = new port("BrandNameTwo","StyleTwo",1);
for (int i = 0; i < 2; i++)
{
cout << *p_port[i] << endl;
}
for (int i = 0; i < 2; i++)
delete p_port[i];
cout << endl;
port p("BrandNameTwo","Style",2);
VintagePort vp("BrandName",19,"NickName",1982);
cout << p << endl;
cout << vp << endl;
}
#ifndef PORT_HPP_
#define PORT_HPP_
#include <iostream>
class port
{
private:
char *brand;
char style[20];
int bottles;
public:
port(const char *br = "none", const char *st = "none", int b = 0);
port(const port &p);
virtual ~port() { delete[] brand; }
port &operator=(const port &p);
port &operator+=(int b);
port &operator-=(int b);
int BottleCount() const { return bottles; }
virtual void Show() const;
friend std::ostream &operator<<(std::ostream &os, const port &p);
};
class VintagePort : public port
{
private:
char *nickname;
int year;
public:
VintagePort();
VintagePort(const char *br, int b, const char *nn, int y);
VintagePort(const VintagePort &vp);
~VintagePort() { delete[] nickname; }
VintagePort &operator=(const VintagePort &vp);
void Show() const;
friend std::ostream &operator<<(std::ostream &out, const VintagePort &vp);
};
#endif
#include "port.hpp"
using std::ostream;
port::port(const char *br, const char *st, int b)
{
brand = new char[strlen(br) + 1];
strcpy(brand, br);
strcpy(style, st);
bottles = b;
}
port::port(const port &p)
{
brand = new char[strlen(p.brand) + 1];
strcpy(brand, p.brand);
strcpy(style, p.style);
bottles = p.bottles;
}
port &port::operator=(const port &p)
{
if (this == &p)
return *this;
delete[] brand;
brand = new char[strlen(p.brand) + 1];
strcpy(brand, p.brand);
strcpy(style, p.style);
bottles = p.bottles;
return *this;
}
port &port::operator+=(int b)
{
bottles += b;
return *this;
}
port &port::operator-=(int b)
{
bottles -= b;
return *this;
}
void port::Show() const
{
std::cout << "Brand: " << brand;
std::cout << "\nKind: " << style;
std::cout << "\nBottles: " << bottles << std::endl;
}
ostream &operator<<(ostream &out, const port &p)
{
out << p.brand << ", " << p.style << ", "
<< p.bottles << std::endl;
return out;
}
VintagePort::VintagePort()
{
nickname = nullptr;
year = 0;
}
VintagePort::VintagePort(const char *br, int b, const char *nn, int y)
: port(br, "vintage", b)
{
year = y;
nickname = new char[strlen(nn) + 1];
strcpy(nickname, nn);
}
VintagePort::VintagePort(const VintagePort &vp) : port(vp)
{
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
}
VintagePort &VintagePort::operator=(const VintagePort &vp)
{
if (this == &vp)
return *this;
port::operator=(vp);
delete[] nickname;
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
return *this;
}
void VintagePort::Show() const
{
std::cout << "\nNickname: " << nickname << std::endl;
port::Show();
}
ostream &operator<<(ostream &out, const VintagePort &vp)
{
out << vp.nickname << ", ";
// operator<<(os, (const port &)vp);
operator<<(out, (const port &)vp);
return out;
}
这里是程序的结果
BrandONe, vintage, 10
BrandNameTwo, StyleTwo, 1
BrandNameTwo, Style, 2
NickName, BrandName, vintage, 19
我是新来的,抱歉,如果我做错了什么
重载和覆盖是完全不同的事情。
在编译时选择重载,使用静态类型。
由于数组元素的类型是 port*
,因此选择了 port&
重载。
如果您想要一个“动态”operator<<
,请创建一个接受基 class 并仅分派给您可以覆盖的虚拟成员函数的函数。
示例:
class port
{
// ...
public:
virtual std::ostream& print(std::ostream* os) const
{
out << brand << ", " << style << ", "
<< bottles << std::endl;
return out;
}
};
std::ostream& operator<<(std::ostream& os, const port& p)
{
return p.print(os);
}
class VintagePort : public port
{
// ...
public:
std::ostream& print(std::ostream& out) const override
{
out << vp.nickname << ", ";
return port::print(out);
}
};