Fork me on GitHub

C++ 运算符重载

14. 运算符重载

14.1 Overloaded operator

  • Just a function with an operator name!
    • Use the operator keyword as a prefix to name operator *(...)
  • Can be a member function
    • Implicit first argument this:
      const String String::operator +(const String& that);
  • Can be a global (free) function
    • Both arguments explicit
      const String operator+(const String& r, const String& l);

14.2 参数传入

  • If it is read-only, pass it in as a const reference.
  • Make member functions const that don't change the class(boolean operators, +, -, etc)
  • For global functions, if the left-hand side changes pass as a reference(assignment operators)

14.3 结果返回

  • Select the return type depending on the expected meaning of the operator. For example,
    • For operator+ you need to generate a new object. Return as a const object so the result cannot be modified as an lvalue.
    • Logical operators should return bool(or int for older compilers)

14.4 The prototypes of operators

  • +-*/%^&|~
    • const T operatorX(const T& left, const T& right) const;
  • !&&||< <= == >= >
    • bool operatorX(const T& left, const T& right) const;
  • []
    • T& T::operator[](int index);
  • operators ++ and --
  • Postfix forms take an int argument -- compiler will pass in 0 as that int
class Integer {
public:
    const Integer& operator++();    // prefix++
    const Integer operator++(int);  // postfix++
    const Integer& operator--();    // prefix--
    const Integer operator--(int);  // postfix--
};

const Integer& Integer::operator++() {
    *this += 1;
    return *this;
}

const Integer Integer::operator++(int) {
    Integer old(*this);
    ++(*this);
    return old;
}
  • Relation operators
    • implement != in terms of ==
    • implement >, >=, <= in terms of <
class Integer {
public:
    bool operator==(const Integer& rhs) const;
    bool operator!=(const Integer& rhs) const;
    bool operator<(const Integer& rhs) const;
    bool operator>(const Integer& rhs) const;
    bool operator<=(const Integer& rhs) const;
    bool operator>=(const Integer& rhs) const;
}

bool Integer::operator==(const Integer& rhs) const {
    return i == rhs.i;
}

bool Integer::operator!=(const Integer& rhs) const {
    return !(*this == rhs);
}

bool Integer::operator<(const Integer& rhs) const {
    return i < rhs.i;
}

// implement lhs > rhs in terms of lhs < rhs
bool Integer::operator>(const Integer& rhs) const {
    return rhs < *this;
}

// implement lhs <= rhs in terms of !(rhs < lhs)
bool Integer::operator<=(const Integer& rhs) const {
    return !(rhs < *this);
}

// implement lhs >= rhs in terms of !(lhs < rhs)
bool Integer::operator>=(const Integer& rhs) const {
    return !(*this < rhs);
}

14.5 赋值

  • 示例:
class Fi {
public:
    Fi(){}
};

class Fee {
public:
    Fee(int) {}
    Fee(const Fi&){}
};

int main() {
    Fee fee = 1;    // Fee(int)
    Fi fi;
    // 拷贝构造
    Fee fum = fi;   // Fee(Fi)
    // 赋值
    fum = fi;
}

14.5.1 Assignment Operator

  • Must be a member function
  • Will be generated for you if you don't provide one
    • Same behavior as automatic copy constructor -- memberwise assignment
  • Check for assignment to self
  • Be sure to assign to all data members
  • Return a reference to *this
T& T::operator=(const T& rhs) {
    // check for self assignment
    if (this != &rhs) {
        // perform assignment
    }
    return *this;
}

14.6 类型转换

  • A conversion operator can be used to convert an object of one class into
    • an object of another class
    • a built-in type
  • Compilers perform implicit conversions using:
    • Single-argument constructors
    • implicit type conversion operators

14.6.1 Single-argument constructors

  • 示例:
class PathName {
    string name;
public:
    PathName(const string&);
    ~PathName();
};

int main()
{
    string abc("abc");
    PathName xyz(abc);  // OK, 拷贝构造
    xyz = abc;          // OK, abc => PathName
}


// 示例二:
class One {
public:
    One(){}
};

class Two {
public:
    Two(const One&) {}
};

void f(Two) {}

int main() {
    One one;
    f(one);     // Wants a Two, has a One
}

14.6.2 Preventing implicit conversions

  • explicit 关键字
  • 示例:
class PathName {
    string name;
public:
    explicit PathName(const string&);
    ~ PathName();
};

int main()
{
    string abc("abc");
    PathName xyz(abc);  // OK!
    xyz = abc;          // Error!
}

14.6.3 Conversion operations

  • Operator conversion

    • Function will be called automatically
    • Return type is same as function name
  • 格式:X::operator T()

    • Operator name is any type descriptor
    • No explicit arguments
    • No return type
    • Compiler will use it as a type conversion from X => T
  • 示例:

class Rational {
public:
    operator double() const;    // Rational to double
};

Rational::operator double() const {
    return numrator_/(double)denominator_;
}

int main()
{
    Rational r(1, 3);
    double d = 1.3 * r; // r => double
}

参考资料:

posted @ 2022-06-17 11:31  小a的软件思考  阅读(29)  评论(0编辑  收藏  举报