#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)