Skip to main content

友元函数及重载运算符

·402 words·2 mins· loading
Raven005
Author
Raven005
A little bit about you
Table of Contents

友元类与友元函数
#

友元就是可以让另一个类或函数访问私有成员的简单写法


#include <iostream>
class Test {
  friend class Test2;
  friend void outPut(const Test &test);

private:
  std::string name;
  unsigned old;
};

class Test2 {
public:
  void outPut(const Test &test) {
    std::cout << test.name << ' ' << test.old << std::endl;
  }
};

void outPut(const Test &test) {
  std::cout << test.name << ' ' << test.old << std::endl;
}

int main() { return 0; }

注意事项:

  • 友元函数会破坏封装性,一般不推荐使用,所带的方便写几个接口函数就解决了
  • 某些运算符的重载必须用到友元的功能,这才是友元的真正用途

总结:友元平常并不推荐使用,不要再纠结友元的语法,只要可以用友元写出必须用友元的重载运算符的就可以了

重载运算符
#

  1. 很多时候我们想让类对象也能像其他基础类型的对象一样进行基础操作,比如"+", “-”, “\*” ,"/", 也可以使用某些运算符"=" , “>>” ,"<<", “()” , “{}”, 但是一般类即使编译器可以识别这些运算符,类对象也无法对这些运算符做出应对,我们必须对类对象定义处理这些运算符的方式
  2. C++提供了定义这些行为的方式,就是 operator 运算符来定义运算符的行为, operator 是一个关键字,告诉编译器我要重载运算符了

注意:

  1. 我们只能重载 C++已有的运算符,所以无法将 ** 这个运算符定义为指数的形式,因为 C++根本没有 ** 这个运算符

  2. C++重载运算符不能改变运算符的元数, 元数 这个概念就是指一个运算符对应的对象数量,比如+必须为a + b ,也就是说+必须有两个对象,那么+就是二元运算符。比如++运算符,就必须写为a++,也就是一元运算符

例子
#

一元运算符
#

++ , --;
[]
()
>>, << // IO or byte
#include <iostream>
#include <string>
#include <vector>

class Test {

  friend std::ostream &operator<<(std::ostream &os, const Test &test);
  friend std::istream &operator>>(std::istream &is, Test &test);

public:
  unsigned cnt = 0;
  std::vector<int> st{1, 2, 3, 4, 5, 6, 7, 8};
  std::string str;
  std::string name;

  void operator++() { ++cnt; }
  void operator--() { --cnt; }
  void operator()() const { std::cout << "hello world" << std::endl; }
  void operator()(const std::string &str) { std::cout << str << std::endl; }
  int operator[](unsigned i) {
    if (i >= 0 && i < st.size())
      return st[i];
    return 0;
  }
};

std::ostream &operator<<(std::ostream &os, const Test &test) {
  os << test.name << std::endl;
  return os;
}

std::istream &operator>>(std::istream &is, Test test) {
  is >> test.name;
  return is;
}

int main() {
  Test test;
  ++test;
  std::cout << test.cnt << std::endl;
  --test;
  std::cout << test.cnt << std::endl;

  for (int i = 0; i < test.st.size(); i++)
    std::cout << test[i] << ' ';

  std::cout << std::endl;

  test();
  test("cxy");
  std::cin >> test.name;
  std::cout << test.name;


  return 0;
}

二元运算符
#

+ , - , * , /
=
> , < , ==

至于三目运算符"?:" 不能重载

注意: “=”类会默认重载,如果不需要可以用"delete"关键字进行修饰

#include <iostream>
#include <string>
#include <vector>

class Test {

public:
  unsigned cnt = 0;

  Test operator+(const Test &test) {
    cnt += test.cnt;
    return *this;
  }
  Test &operator=(const Test &test) {
    if (this == &test)
      return *this;

    cnt = test.cnt;
    return *this;
  }

  bool operator<(const Test &test) { return cnt < test.cnt; }
  bool operator>(const Test &test) { return cnt > test.cnt; }
  bool operator==(const Test &test) { return cnt == test.cnt; }
};

int main() {
  Test test;
  // std::cout << test.cnt << std::endl;
  test.cnt = 20;
  Test test2;
  Test test3 = test + test2;
  std::cout << test3.cnt << std::endl;

  return 0;
}