在友元函数定义时。是静态的,因此有以下特点:
所以写友元函数的原则:类的友元函数,传入的参数,只能是其本身的指针。
运行时:类的友元函数还是遵循多态的,所以,友元函数最好还是写在基类中,这样它就可以形成多态了。
总结:编译期,友元函数具有静态特性。运行期,多态
class Base {
public:
typedef std::shared_ptr<Base> ptr;
friend void visit(Base::ptr m);
protected:
int b = 0;
private:
int age = 0;
};
class Derive : public Base {
typedef std::shared_ptr<Derive> ptr;
friend void visitD(Base::ptr);
private:
int n = 0;
};
派生类的友元函数,不能通过基类指针访问基类的protected成员变量(友元函数不具备继承,传递的特性,同时具备单向性)
class Base {
public:
typedef std::shared_ptr<Base> ptr;
friend void visit(std::shared_ptr<Derive> m);
protected:
int b = 1;
private:
int age = 2;
};
class Derive : public Base {
public:
typedef std::shared_ptr<Derive> ptr;
friend void visitD(Derive::ptr);
private:
int n = 3;
};
基类的友元函数,不能通过派生类的指针访问基类的protected 成员
class Shape {
public:
friend bool PointInShape(const Point<double>& cur, std::shared_ptr<const Shape> s);
friend bool PointOnShape(const Point<double>& cur, std::shared_ptr<const Shape> s);
enum ShapeType {
M,
V,
CONN,
Poly,
UNKNON
};
typedef std::shared_ptr<Shape> ptr;
Shape(std::string& line)
:m_level(0) {
static uint64_t s_key = 0;
m_key = s_key;
s_key++;
std::stringstream ss;
ss << line;
double x;
double y;
while(ss >> x && ss >> y) {
m_points.push_back(Point<double>(x,y));
}
};
virtual ~Shape(){};
// plot 内联 ----
void plot() const {
size_t pNum = m_points.size();
std::vector<double> x(pNum + 1);
std::vector<double> y(pNum + 1);
for(size_t i = 0; i < pNum; ++i) {
x[i] = (m_points[i].getX());
y[i] = (m_points[i].getY());
}
x[pNum] = (m_points[0].getX());
y[pNum] = (m_points[0].getY());
std::string c = getColor();
plt::plot(x, y, c);
};
size_t size() { return m_points.size();};
int getLevel() { return m_level;};
uint64_t getKey() const {return m_key;};
const Point<double>& operator[] (std::size_t position) const{
return m_points[position];
};
std::string ToString() const;
protected:
virtual const std::string getColor() const = 0;
std::vector<Point<double>> m_points;
int m_level = 0;
uint64_t m_key = 0;
};
为什么PointInShape报错。