崔毅东 C++程序设计入门(下) 第8单元:年年岁岁花相似– 运算符重载 笔记

在这里插入图片描述

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

// For more details about "string", "vector",
//    and "stringstream", please refer to book
//    <<The C++ Standard Library - 
//      A Tutorial and Reference>>

using namespace std;
int main() {
    
    // Student1~4
    string sname("Student"), snumber("1");
    for (int i = 1; i <= 4; i++) {
        cout << sname + snumber << endl; 
        snumber[0]++;
    }

    // Student5~7
    // copy the contents from sname;
    vector<char> vname(sname.begin(), sname.end());
    vname.resize(vname.size() + 1);
    for (int i = 5; i <= 7; i++) {
        vname[vname.size() - 1] = static_cast<char>(i + '0');
        for (unsigned int j = 0; j < vname.size(); j++)
            cout << vname[j];
        cout << endl;
    }
    
    // Student8~10
    stringstream sequenceNo("", ios::out|ios::app);
    for (int i = 8; i <= 10; i++) {
        sequenceNo.str("Student");    // Set the contents
        sequenceNo << i;       // convert integer to string
        cout << sequenceNo.str() << endl; 
    }
    
    // compare two string and show the result in bool type
    cout << boolalpha << "Student1 > Student2 : " <<
            (string("Student1") > string("Student2"));
            
    return 0;            
}

在这里插入图片描述

第02节:有理数类

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
Rational.h

#ifndef RATIONL_H
#define RATIONL_H
#include <string>

using namespace std;

class Rational {
public:
  Rational();
  Rational(long numerator, long denominator);
  long getNumerator();
  long getDenominator();
  Rational add(Rational &secondRational);
  Rational subtract(Rational &secondRational);
  Rational multiply(Rational &secondRational);
  Rational divide(Rational &secondRational);
  int compareTo(Rational &secondRational);
  bool equals(Rational &secondRational);
  int intValue();
  double doubleValue();
  string toString();

private:
  long numerator_;
  long denominator_;
  static long gcd(long n, long d);
};

#endif

Rational.cpp

#include <iostream>
#include <sstream>

#include <cmath>

#include "Rational.h"

using namespace std;

Rational::Rational()
{
  numerator_ = 0;
  denominator_ = 1;
}

Rational::Rational(long numerator, long denominator)
{
  long factor = gcd(numerator, denominator);
  numerator_ = ((denominator > 0) ? 1 : -1) * numerator / factor;
  denominator_ = abs(denominator) / factor;
}

long Rational::getNumerator()
{
  return numerator_;
}

long Rational::getDenominator()
{
  return denominator_;
}

/** Find GCD of two numbers */
long Rational::gcd(long n, long d) {
  long n1 = abs(n);
  long n2 = abs(d);
  int gcd = 1;

  for (int k = 1; k <= n1 && k <= n2; k++)
  {
    if (n1 % k == 0 && n2 % k == 0)
      gcd = k;
  }

  return gcd;
}

Rational Rational::add(Rational &secondRational)
{
  long n = numerator_ * secondRational.getDenominator() +
    denominator_ * secondRational.getNumerator();
  long d = denominator_ * secondRational.getDenominator();
  return Rational(n, d);
}

Rational Rational::subtract(Rational &secondRational)
{
  long n = numerator_ * secondRational.getDenominator()
    - denominator_ * secondRational.getNumerator();
  long d = denominator_ * secondRational.getDenominator();
  return Rational(n, d);
}

Rational Rational::multiply(Rational &secondRational)
{
  long n = numerator_ * secondRational.getNumerator();
  long d = denominator_ * secondRational.getDenominator();
  return Rational(n, d);
}

Rational Rational::divide(Rational &secondRational)
{ // We don't handle the case of secondRational being 0
  long n = numerator_ * secondRational.getDenominator();
  // private data in another object of the same type
  //    can be directly visited. 
  long d = denominator_ * secondRational.numerator_; 
  return Rational(n, d);
}

int Rational::compareTo(Rational &secondRational)
{
  Rational temp = this->subtract(secondRational);
  if (temp.getNumerator() < 0)
    return -1;
  else if (temp.getNumerator() == 0)
    return 0;
  else
    return 1;
}

bool Rational::equals(Rational &secondRational)
{
  if (this->compareTo(secondRational) == 0)
    return true;
  else
    return false;
}

int Rational::intValue()
{
  return getNumerator() / getDenominator();
}

double Rational::doubleValue()
{
  return 1.0 * getNumerator() / getDenominator();
}

//string Rational::toString()
//{
//  char s1[20], s2[20];
//  itoa(numerator_, s1, 10); // Convert int to string s1
//  itoa(denominator_, s2, 10); // Convert int to string s2
//
//  if (denominator_ == 1)
//    return string(s1);
//  else
//    return string(strcat(strcat(s1, "/"), s2));
//}

string Rational::toString()
{
  stringstream stringStream;
  if (denominator_ != 1) {
    stringStream << numerator_ << "/" << denominator_;
  } else {
    stringStream << numerator_;  
  }
  
  return string(stringStream.str());
}

TestRationalClass.cpp

#include <iostream>
#include "Rational.h"
using namespace std;

int main()
{
  // Create and initialize two rational numbers r1 and r2.
  Rational r1(4, 2);
  Rational r2(2, 3);

  // Test toString, add, substract, multiply, and divide
  cout << r1.toString() << " + " << r2.toString() << " = " << 
          r1.add(r2).toString() << endl;
  cout << r1.toString() << " - " << r2.toString() << " = " << 
          r1.subtract(r2).toString() << endl;
  cout << r1.toString() << " * " << r2.toString() << " = " << 
          r1.multiply(r2).toString() << endl;
  cout << r1.toString() << " / " << r2.toString() << " = " << 
          r1.divide(r2).toString() << endl;

  // Test intValue and double
  cout << "r2.intValue()" << " is " << r2.intValue() << endl;
  cout << "r2.doubleValue()" << " is " << r2.doubleValue() << endl;

  // Test compareTo and equal
  cout << "r1.compareTo(r2) is " << r1.compareTo(r2) << endl;
  cout << "r2.compareTo(r1) is " << r2.compareTo(r1) << endl;
  cout << "r1.compareTo(r1) is " << r1.compareTo(r1) << endl;
  cout << "r1.equals(r1) is " << r1.equals(r1) << endl;
  cout << "r1.equals(r2) is " << r1.equals(r2) << endl;

  return 0;
}

在这里插入图片描述

第03节:运算符函数以及简写运算符重载

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

第04节:重载[]运算符

在这里插入图片描述在这里插入图片描述

第05节:重载一元运算符

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

第06节:重载流提取/插入运算符以及对象转换运算符

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
u08s06 - 如果将流操作运算符重载为类的成员函数…
如果将流操作运算符重载为类的成员函数,会发生哪些反常的事情?

打开你的脑洞,用代码说明
答:会使得你将不得不使用如下反人类的方式调用

扫描二维码关注公众号,回复: 5316737 查看本文章

MyCircle c1;

c1 >> std::cin;

c1 << std::cout;

(by wohaaitinciu)

第07节:新有理数类的示例

在这里插入图片描述在这里插入图片描述在这里插入图片描述
NewRational.h

#ifndef NEWRATIONL_H
#define NEWRATIONL_H

#include <string>
using namespace std; 

class Rational
{
public:
  Rational();
  Rational(long numerator, long denominator);
  long getNumerator();
  long getDenominator();
  Rational add(Rational &secondRational);
  Rational subtract(Rational &secondRational);
  Rational multiply(Rational &secondRational);
  Rational divide(Rational &secondRational);
  int compareTo(Rational &secondRational);
  bool equals(Rational &secondRational);
  int intValue();
  double doubleValue();
  string toString();

  // Define function operators for relational operators
  bool operator<(Rational &secondRational);
  bool operator<=(Rational &secondRational);
  bool operator>(Rational &secondRational);
  bool operator>=(Rational &secondRational);
  bool operator!=(Rational &secondRational);
  bool operator==(Rational &secondRational);

  // Define function operators for arithmetic operators
  Rational operator+(Rational &secondRational);
  Rational operator-(Rational &secondRational);
  Rational operator*(Rational &secondRational);
  Rational operator/(Rational &secondRational);

  // Define function operators for shorthand operators
  Rational operator+=(Rational &secondRational);
  Rational operator-=(Rational &secondRational);
  Rational operator*=(Rational &secondRational);
  Rational operator/=(Rational &secondRational);

  // Define function operator []
  long& operator[](const int &index);

  // Define function operators for prefix ++ and --
  Rational operator++();
  Rational operator--();

  // Define function operators for postfix ++ and --
  Rational operator++(int dummy);
  Rational operator--(int dummy);

  // Define function operators for unary + and -
  Rational operator+();
  Rational operator-();

  // Define the output and input operator
  friend ostream &operator<<(ostream &stream, Rational &rational);
  friend istream &operator>>(istream &stream, Rational &rational);

  // Define function operator for conversion
  operator double();

private:
  long numerator_;
  long denominator_;
  static long gcd(long n, long d);
};

#endif

NewRational.cpp

#include <iostream>
#include <sstream>

#include <cmath>
#include <cstdlib>

#include "NewRational.h"

using namespace std;

Rational::Rational()
{
  numerator_ = 0;
  denominator_ = 1;
}

Rational::Rational(long numerator, long denominator)
{
  long factor = gcd(numerator, denominator);
  numerator_ = ((denominator > 0) ? 1 : -1) * numerator / factor;
  denominator_ = abs(denominator) / factor;
}

long Rational::getNumerator()
{
  return numerator_;
}

long Rational::getDenominator()
{
  return denominator_;
}

/** Find GCD of two numbers */
long Rational::gcd(long n, long d) {
  long n1 = abs(n);
  long n2 = abs(d);
  int gcd = 1;

  for (int i = 1; i <= n1 && i <= n2; i++)
  {
    if (n1 % i == 0 && n2 % i == 0)
      gcd = i;
  }

  return gcd;
}

Rational Rational::add(Rational &secondRational)
{
  long n = numerator_ * secondRational.getDenominator() +
    denominator_ * secondRational.getNumerator();
  long d = denominator_ * secondRational.getDenominator();
  return Rational(n, d);
}

Rational Rational::subtract(Rational &secondRational)
{
  long n = numerator_ * secondRational.getDenominator() -
           denominator_ * secondRational.getNumerator();
  long d = denominator_ * secondRational.getDenominator();
  return Rational(n, d);
}

Rational Rational::multiply(Rational &secondRational)
{
  long n = numerator_ * secondRational.getNumerator();
  long d = denominator_ * secondRational.getDenominator();
  return Rational(n, d);
}

Rational Rational::divide(Rational &secondRational)
{
  long n = numerator_ * secondRational.getDenominator();
  long d = denominator_ * secondRational.numerator_;
  return Rational(n, d);
}

int Rational::compareTo(Rational &secondRational)
{
  Rational temp = this->subtract(secondRational);
  if (temp.getNumerator() < 0)
    return -1;
  else if (temp.getNumerator() == 0)
    return 0;
  else
    return 1;
}

bool Rational::equals(Rational &secondRational)
{
  if (this->compareTo(secondRational) == 0)
    return true;
  else
    return false;
}

int Rational::intValue()
{
  return getNumerator() / getDenominator();
}

double Rational::doubleValue()
{
  return 1.0 * getNumerator() / getDenominator();
}

string Rational::toString() 
{
  stringstream stringStream;
  if (denominator_ != 1) {
    stringStream << numerator_ << "/" << denominator_;
  } else {
    stringStream << numerator_;  
  }
  
  return string(stringStream.str());
}

// Define function operators for relational operators
bool Rational::operator<(Rational &secondRational)
{
  return (this->compareTo(secondRational) < 0);
}

bool Rational::operator<=(Rational &secondRational)
{
  return (this->compareTo(secondRational) <= 0);
}

bool Rational::operator>(Rational &secondRational)
{
  return (this->compareTo(secondRational) > 0);
}

bool Rational::operator>=(Rational &secondRational)
{
  return (this->compareTo(secondRational) >= 0);
}

bool Rational::operator!=(Rational &secondRational)
{
  return (this->compareTo(secondRational) != 0);
}

bool Rational::operator==(Rational &secondRational)
{
  return (this->compareTo(secondRational) == 0);
}

// Define function operators for arithmetic operators
Rational Rational::operator+(Rational &secondRational)
{
  return this->add(secondRational);
}

Rational Rational::operator-(Rational &secondRational)
{
  return this->subtract(secondRational);
}

Rational Rational::operator*(Rational &secondRational)
{
  return this->multiply(secondRational);
}

Rational Rational::operator/(Rational &secondRational)
{
  return this->divide(secondRational);
}

// Define function operators for shorthand operators
Rational Rational::operator+=(Rational &secondRational)
{
  *this = this->add(secondRational);
  return (*this);
  //return this->add(secondRational);
}

Rational Rational::operator-=(Rational &secondRational)
{
  *this = this->subtract(secondRational);
  return (*this);
}

Rational Rational::operator*=(Rational &secondRational)
{
  *this = this->multiply(secondRational);
  return (*this);
}

Rational Rational::operator/=(Rational &secondRational)
{
  *this = this->divide(secondRational);
  return *this;
}

// Define function operator []
long& Rational::operator[](const int &index)
{
  if (index == 0)
    return numerator_;
  else if (index == 1)
    return denominator_;
  else
  {
    cout << "subscript error" << endl;
    exit(0);
  }
}

// Define function operators for prefix ++ and --
Rational Rational::operator++()
{
  numerator_ += denominator_;
  return *this;
}

Rational Rational::operator--()
{
  numerator_ -= denominator_;
  return *this;
}

// Define function operators for postfix ++ and --
Rational Rational::operator++(int dummy)
{
  Rational temp(numerator_, denominator_);
  numerator_ += denominator_;
  return temp;
}

Rational Rational::operator--(int dummy)
{
  Rational temp(numerator_, denominator_);
  numerator_ -= denominator_;
  return temp;
}

// Define function operators for unary + and -
Rational Rational::operator+()
{
  return *this;
}

Rational Rational::operator-()
{
  numerator_ *= -1;
  return *this;
}

// Define the output and input operator
ostream &operator<<(ostream &str, Rational &rational)
{
  // cout << rational.numerator_ << " / " << rational.denominator_;
  cout << rational.toString();
  return str;
}

istream &operator>>(istream &str, Rational &rational)
{
  cout << "Enter numerator: ";
  str >> rational.numerator_;

  cout << "Enter denominator: ";
  str >> rational.denominator_;
  return str;
}

// Define function operator for conversion
Rational::operator double()
{
  return doubleValue();
}

TestNewRationalClass.cpp

#include <iostream>
#include <string>

#include "NewRational.h"

using namespace std;

int main()
{
  // Create and initialize two rational numbers r1 and r2.
  Rational r1(4, 2);
  Rational r2(2, 3);

  // Test relational operators
  cout << r1 << " > " << r2 << " is " << (r1 > r2) << endl;
  cout << r1 << " < " << r2 << " is " << (r1 < r2) << endl;
  cout << r1 << " == " << r2 << " is " << (r1 == r2) << endl;
  cout << r1 << " != " << r2 << " is " << (r1 != r2) << endl;

  // Test toString, add, substract, multiply, and divide operators
  cout << r1 << " + " << r2 << " = " << r1 + r2 << endl;
  cout << r1 << " - " << r2 << " = " << r1 - r2 << endl;
  cout << r1 << " * " << r2 << " = " << r1 * r2 << endl;
  cout << r1 << " / " << r2 << " = " << r1 / r2 << endl;

  // Test shorthand operators
  Rational r3(1, 2);
  r3 += r1;
  cout << "r3 is " << r3 << endl;

  // Test function operator []
  Rational r4(1, 2);
  r4[0] = 3; r4[1] = 4;
  cout << "r4 is " << r4 << endl;

  // Test function operators for ++ and --
  r3 = r4++;
  cout << "r3 is " << r3 << endl;
  cout << "r4 is " << r4 << endl;

  // Test function operator for conversion
  cout << "1 + " << r4 << " is " << (1 + r4) << endl;

  return 0;
}

在这里插入图片描述在这里插入图片描述

第08节:重载赋值运算符

在这里插入图片描述在这里插入图片描述
Date.h

#ifndef DATE_H
#define DATE_H

class Date
{
public:
  Date(int newYear, int newMonth, int newDay);
  int getYear();
  void setYear(int newYear);

private:
  int year;
  int month;
  int day;
};

#endif

Date.cpp

#include "Date.h"

Date::Date(int newYear, int newMonth, int newDay)
{
  year = newYear;
  month = newMonth;
  day = newDay;
}

int Date::getYear()
{
  return year;
}

void Date::setYear(int newYear)
{
  year = newYear;
}

Person2.h

#include "Date.h"

class Person
{
public:
  Person(int id, int year, int month, int day);
  Person(Person &);
  ~Person(); 
  const Person operator=(const Person& person);
  int getId();
  Date * getBirthDate() const; // Return the pointer of the object

private:
  int id;
  Date *birthDate; // The pointer of the object
};

Person2.cpp

#include "Person2.h"

Person::Person(int id, int year, int month, int day)
{
  this -> id = id;
  birthDate = new Date(year, month, day);
}

Person::Person(Person &person)
{
  id = person.id;
  Date *p = person.getBirthDate();
  birthDate = new Date(*p);
}

Person::~Person()
{
    delete birthDate;
}

const Person Person::operator=(const Person& person)
{
  id = person.id;
  Date *p = person.getBirthDate();
  birthDate = new Date(*p);    
  return *this;
}



int Person::getId()
{
  return id;
}

Date * Person::getBirthDate() const
{
  return birthDate; // Return the pointer of the object
}

DefaultAssignmentDemo.cpp

#include <iostream>
#include "Person2.h"
using namespace std;

void displayPerson(Person &person1, Person &person2)
{
  cout << "\tperson1 id: " << person1.getId() << endl;
  cout << "\tperson1 birth year: " <<
    person1.getBirthDate() -> getYear() << endl;
  cout << "\tperson2 id: " << person2.getId() << endl;
  cout << "\tperson2 birth year: " <<
    person2.getBirthDate() -> getYear() << endl;
}

int main()
{
  Person person1(111, 1970, 5, 3);
  Person person2(222, 2000, 11, 8);

  cout << "After creating person1 and person2" << endl;
  displayPerson(person1, person2);

  person1 = person2; // Copy person2 to person1

  cout << "\nAfter copying person2 to person1" << endl;
  displayPerson(person1, person2);

  person2.getBirthDate() -> setYear(1963);

  cout << "\nAfter modifying person2's birthDate" << endl;
  displayPerson(person1, person2);

  cout << "\n" << (person1.getBirthDate() == person2.getBirthDate());
  return 0;
}

在这里插入图片描述
u08s08 - 赋值运算符与拷贝构造函数
赋值运算符与拷贝构造函数有很多联系。

比如说,涉及到对象深拷贝构造的时候,我们同时也要为赋值运算符提供重载的深拷贝版本。

那么,下面这几行代码,到底是调用拷贝构造函数还是调用赋值运算符?

尤其是第3行,为什么?

Circle c1;
Circle c2(c1);
Circle c3 = c2;
c1 = c3;
答:Circle c2(c1); // copy ,定义对象c2,调用拷贝构造函数构造对象

Circle c3 = c2; // copy ,定义对象c3,调用拷贝构造函数构造对象

c1 = c3; // assignment(by zj060607)

第09节:运算符重载的更多问题

在这里插入图片描述在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/dldldl1994/article/details/87079220
今日推荐