构造函数、析构函数
# include <iostream>
using namespace std;
class Person
{
private : int age; public : Person ( ) { cout << "构造函数的调用,无参" << endl; } Person ( int a) { age = a; cout << "构造函数的调用, 含参" << endl; } Person ( const Person& p) { this -> age = p. age; cout << "构造函数的调用,拷贝" << endl; } ~ Person ( ) { cout << "析构函数的调用" << endl; } int getAge ( ) { return age; }
} ; void test ( )
{ Person p1; Person p2 = Person ( 10 ) ; Person p3 = Person ( p2) ; Person p4 = 10 ; Person p5 = p4;
} int main ( )
{ test ( ) ;
}
初始化列表
# include <iostream>
using namespace std;
class Person
{
public : int age; int height; Person ( int a, int b) : age ( a) , height ( b) { ; }
} ; void test ( )
{ Person man ( 28 , 180 ) ; cout << man. age << endl << man. height << endl;
} int main ( )
{ test ( ) ;
}
常函数、常对象
# include <iostream>
using namespace std; class Person
{
public : void showPerson ( ) const { age = 30 ; height = 180 ; } void change ( ) { age = 40 ; height = 166 ; } int age; mutable int height;
} ; void test1 ( )
{ Person p; p. showPerson ( ) ;
} void test2 ( )
{ const Person p; p. age = 22 ; p. height = 175 ; p. showPerson ( ) ; p. change ( ) ;
} int main ( )
{ test1 ( ) ; test2 ( ) ;
}
运算符重载
+ 运算符 重载
# include <iostream>
using namespace std; class Person
{
public : int age; int height; Person operator + ( const Person & p) { Person temp; temp. age = this -> age + p. age; temp. height = this -> height + p. height; return temp; }
} ;
Person operator + ( const Person& p1, const Person& p2)
{ Person temp; temp. age = p1. age + p2. age; temp. height = p1. height + p2. height; return temp;
} void test ( )
{ Person p1; p1. age = 22 ; p1. height = 166 ; Person p2; p2. age = 28 ; p2. height = 134 ; Person p3 = p1 + p2; cout << p3. age << endl << p3. height << endl; Person p3 = p3 + 66 ;
} int main ( )
{ test ( ) ;
}
<< 运算符 重载
# include <iostream>
using namespace std; class Person
{ friend ostream& operator << ( ostream& , const Person& ) ; public : Person ( int age, int height) : age ( age) , height ( height) { cout << "调用了构造函数" << endl; } private : int age; int height;
} ;
ostream& operator << ( ostream& cout, const Person& p)
{ cout << "[ age = " << p. age << ", height = " << p. height << " ]" ; return cout;
} void test ( )
{ Person p1 ( 22 , 166 ) ; cout << p1 << endl;
} int main ( )
{ test ( ) ;
}
自增运算符 重载
#include <iostream>
using namespace std;class MyInteger
{friend ostream& operator<<(ostream&, MyInteger);public:MyInteger(int a) :num(a){cout << "调用了构造函数" << endl;}// 前置递增MyInteger& operator++(){num++;return *this;}// 后置递增MyInteger operator++(int) // int 代表占位参数,可以用于区分前置和后置递增{// 先记录当前结果MyInteger temp = *this;// 后将自己进行递增num++;return temp;}private:int num;
};ostream& operator<<(ostream& cout, MyInteger obj)
{cout << obj.num;return cout;
}void test()
{MyInteger myint = 0;cout << ++(++myint) << endl; // 输出:2cout << myint << endl; // 输出:2cout << myint++ << endl; // 输出:2cout << myint<< endl; // 输出:3
}int main()
{test();
}
赋值运算符 重载
#include <iostream>
using namespace std;class Person
{
public:Person(int age){this->age = new int(age);}~Person(){if (age != NULL){delete age;age = NULL;}}// 赋值运算符重载Person& operator=(const Person& obj){*age = *obj.age;return *this;}int* age;
};void test()
{Person p1(10);cout << "p1的年龄为:" << *p1.age << endl; // 输出结果:10Person p2(20);cout << "p2的年龄为:" << *p2.age << endl; // 输出结果:20Person p3(30);cout << "p3的年龄为:" << *p3.age << endl; // 输出结果:30// 这不是拷贝构造函数,拷贝构造函数也是一种构造函数// 这里是赋值语句,对象的赋值,编译器默认的行为是:将某对象的所有属性复制一份到另一个对象里面// 因为默认行为的直接复制,对于需要浅拷贝的内容没什么影响,但是对于需要深拷贝的内容影响很大// 为了避免恶劣影响,我们需要重载赋值运算符p3 = p2 = p1;cout << "修改后的p2的年龄为:" << *p2.age << endl; // 输出结果:10cout << "修改后的p3的年龄为:" << *p3.age << endl; // 输出结果:10
}int main()
{test();
}
关系运算符 重载
# include <iostream>
# include <string>
using namespace std; class Person
{
public : string name; int age; Person ( string name, int age) : name ( name) , age ( age) { ; } bool operator == ( const Person& obj) { if ( name == obj. name && age == obj. age) { return true ; } return false ; } bool operator != ( const Person& obj) { if ( name == obj. name && age == obj. age) { return false ; } return true ; } } ; void test ( )
{ Person p1 ( "Jack" , 18 ) ; Person p2 ( "Jack" , 18 ) ; Person p3 ( "Tom" , 18 ) ; if ( p1 == p2) cout << "p1 和 p2 相等" << endl; if ( p1 != p3) cout << "p1 和 p3 不相等" << endl;
} int main ( )
{ test ( ) ;
}
函数调用运算符 重载
#include <iostream>
#include <string>
using namespace std;class MyPrint
{
public:// 重载函数调用运算符void operator()(string text, string end="\n"){cout << text << end;}
};class MyAdd
{
public:// 重载函数调用运算符int operator()(int a, int b){return a + b;}
};void test()
{MyPrint print;MyAdd add;print("hello world"); // 由于使用起来非常类似于函数调用,因此称为仿函数string res = to_string(add(10, 20));print(res);// 匿名函数对象 -> MyAdd()cout << MyAdd()(100, 100) << endl;
}int main()
{test();
}
继承知识补充
多态
基础应用
# include <iostream>
# include <string>
using namespace std; class Animal
{
public : virtual void speak ( ) { cout << "动物在叫" << endl; }
} ; class Cat : public Animal
{
public : void speak ( ) { cout << "猫在叫" << endl; }
} ; class Dog : public Animal
{
public : void speak ( ) { cout << "狗在叫" << endl; }
} ;
void doSpeak ( Animal& animal)
{ animal. speak ( ) ;
} void test ( )
{ Cat cat; Dog dog; doSpeak ( cat) ; doSpeak ( dog) ;
} int main ( )
{ test ( ) ;
}
进阶应用
# include <iostream>
# include <string>
using namespace std; class abstractDrinking
{
public : virtual void Boil ( ) = 0 ; virtual void Brew ( ) = 0 ; virtual void PourInCup ( ) = 0 ; virtual void PutSomething ( ) = 0 ; void make ( ) { Boil ( ) ; Brew ( ) ; PourInCup ( ) ; PutSomething ( ) ; }
} ;
class Coffee : public abstractDrinking
{
public : virtual void Boil ( ) { cout << "煮熟自来水" << endl; } virtual void Brew ( ) { cout << "冲泡咖啡" << endl; } virtual void PourInCup ( ) { cout << "倒入迷你的咖啡杯中" << endl; } virtual void PutSomething ( ) { cout << "加入一些糖" << endl; }
} ;
class Tea : public abstractDrinking
{
public : virtual void Boil ( ) { cout << "煮熟矿泉水" << endl; } virtual void Brew ( ) { cout << "冲泡茶叶" << endl; } virtual void PourInCup ( ) { cout << "倒入经典的茶杯中" << endl; } virtual void PutSomething ( ) { cout << "加入一些香料" << endl; }
} ;
void makeDrink ( abstractDrinking* drink)
{ drink-> make ( ) ; delete drink;
} void test ( )
{ makeDrink ( new Coffee) ; makeDrink ( new Tea) ;
} int main ( )
{ test ( ) ;
}
高级应用 (经典)
# include <iostream>
# include <string>
using namespace std;
class CPU
{
public : virtual void calculate ( ) = 0 ;
} ; class VideoCard
{
public : virtual void display ( ) = 0 ;
} ; class Memory
{
public : virtual void storage ( ) = 0 ;
} ;
class IntelCPU : public CPU
{
public : virtual void calculate ( ) { cout << "Intel 的 CPU 开始工作了" << endl; }
} ; class IntelVideoCard : public VideoCard
{
public : virtual void display ( ) { cout << "Intel 的 VideoCard 开始工作了" << endl; }
} ; class IntelMemory : public Memory
{
public : virtual void storage ( ) { cout << "Intel 的 Memory 开始工作了" << endl; }
} ;
class LenovoCPU : public CPU
{
public : virtual void calculate ( ) { cout << "Lenovo 的 CPU 开始工作了" << endl; }
} ; class LenovoVideoCard : public VideoCard
{
public : virtual void display ( ) { cout << "Lenovo 的 VideoCard 开始工作了" << endl; }
} ; class LenovoMemory : public Memory
{
public : virtual void storage ( ) { cout << "Lenovo 的 Memory 开始工作了" << endl; }
} ;
class Computer
{
public : Computer ( CPU* cpu, VideoCard* vc, Memory* mem) : cpu ( cpu) , vc ( vc) , mem ( mem) { ; } void work ( ) { cpu-> calculate ( ) ; vc-> display ( ) ; mem-> storage ( ) ; } ~ Computer ( ) { if ( cpu != NULL ) { delete cpu; cpu = NULL ; } if ( vc != NULL ) { delete vc; vc = NULL ; } if ( mem != NULL ) { delete mem; mem = NULL ; } } private : CPU* cpu; VideoCard* vc; Memory* mem;
} ; void test ( )
{ CPU* intelCpu = new IntelCPU; VideoCard* intelCard = new IntelVideoCard; Memory* intelMem = new IntelMemory; Computer* computer1 = new Computer ( intelCpu, intelCard, intelMem) ; computer1-> work ( ) ; delete computer1; computer1 = NULL ; cout << "------------------------------" << endl; Computer* computer2 = new Computer ( new LenovoCPU, new LenovoVideoCard, new LenovoMemory) ; computer2-> work ( ) ; delete computer2; computer2 = NULL ; cout << "------------------------------" << endl; Computer* computer3 = new Computer ( new IntelCPU, new LenovoVideoCard, new LenovoMemory) ; computer3-> work ( ) ; delete computer3; computer3 = NULL ;
} int main ( )
{ test ( ) ;
}
文件操作
# include <iostream>
# include <fstream>
# include <string> using namespace std;
void writeText ( )
{ ofstream file; file. open ( "test.txt" , ios:: app) ; file << "姓名:张三" << endl; file << "性别:男" << endl; file << "年龄:28" << endl; file. close ( ) ;
} void readText ( )
{ ifstream file; file. open ( "test.txt" , ios:: in) ; if ( ! file. is_open ( ) ) { cout << "文件打开失败!" << endl; return ; } char c; while ( ( c = file. get ( ) ) != EOF ) { cout << c; } file. close ( ) ;
} class Person
{
public : char m_Name[ 64 ] ; int m_Age;
} ; void writeBinary ( )
{ ofstream file; file. open ( "person.txt" , ios:: out | ios:: binary) ; Person p = { "张三" , 28 } ; file. write ( ( const char * ) & p, sizeof ( Person) ) ; file. close ( ) ;
} void readBinary ( )
{ ifstream file; file. open ( "person.txt" , ios:: in | ios:: binary) ; if ( ! file. is_open ( ) ) { cout << "文件打开失败" << endl; } Person p; file. read ( ( char * ) & p, sizeof ( Person) ) ; cout << "姓名:" << p. m_Name << "年龄:" << p. m_Age << endl; file. close ( ) ;
} int main ( )
{ writeText ( ) ; readText ( ) ; writeBinary ( ) ; readBinary ( ) ;
}
函数模板的重载
# include <iostream>
# include <string>
using namespace std; class Person
{
public : Person ( string name, int age) { this -> m_Name = name; this -> m_Age = m_Age; } string m_Name; int m_Age;
} ; template < typename T >
bool myCompare ( T & a, T & b)
{ if ( a == b) return true ; else return false ;
}
template < >
bool myCompare ( Person& p1, Person& p2)
{ if ( p1. m_Name == p2. m_Name && p1. m_Age == p2. m_Age) return true ; else return false ;
} void test ( )
{ int a = 10 ; int b = 10 ; bool ret = myCompare ( a, b) ; cout << ret << endl; Person p1 ( "张三" , 18 ) ; Person p2 ( "李四" , 28 ) ; bool res = myCompare ( p1, p2) ; cout << res << endl;
} int main ( )
{ test ( ) ;
}
类模板
# include <iostream>
# include <string>
using namespace std; template < class Type1 , class Type2 = int >
class Person
{
public : Person ( Type1 name, Type2 age) { this -> m_Name = name; this -> m_Age = age; } void showPerson ( ) { cout << "name: " << m_Name << " age: " << m_Age << endl; } Type1 m_Name; Type2 m_Age;
} ; void test ( )
{ Person< string, int > p1 ( "张三" , 18 ) ; p1. showPerson ( ) ; Person< string> p2 ( "李四" , 28 ) ; p2. showPerson ( ) ;
} int main ( )
{ test ( ) ;
}
# include <iostream>
# include <string>
using namespace std; template < class T1 , class T2 >
class Person
{
public : Person ( T1 name, T2 age) { this -> m_Name = name; this -> m_Age = age; } void showPerson ( ) { cout << "姓名:" << this -> m_Name << " 年龄:" << this -> m_Age << endl; } T1 m_Name; T2 m_Age;
} ;
void printPerson1 ( Person< string, int > & p)
{ p. showPerson ( ) ;
}
template < class T1 , class T2 >
void printPerson2 ( Person< T1, T2> & p)
{ p. showPerson ( ) ;
}
template < class T >
void printPerson3 ( T& p)
{ p. showPerson ( ) ;
} void test ( )
{ Person< string, int > p1 ( "张三" , 28 ) ; printPerson1 ( p1) ; Person< string, int > p2 ( "李四" , 18 ) ; printPerson2 ( p2) ; Person< string, int > p3 ( "王五" , 38 ) ; printPerson3 ( p3) ;
} int main ( )
{ test ( ) ;
}
类模板与继承
#include <iostream>
#include <string>
using namespace std;// 类模板与继承
template <class T>
class Base
{T m_Name;
};// 必须要知道父类中的T类型,才能继承给子类
class Son : public Base<int>
{};void test1()
{Son s1;
}// 如果想灵活指定父类中T类型,子类也需要变类模板
template <class T1, class T2>
class Son2 : public Base<T2>
{
public:Son2(){cout << "T1 的类型为:" << typeid(T1).name() << endl;cout << "T2 的类型为:" << typeid(T2).name() << endl;}
};void test2()
{Son2<int, char> s2;
}int main()
{test1();test2();
}
类模板函数的类外实现
#include <iostream>
#include <string>
using namespace std;template<class T1, class T2>
class Person
{
public:Person(T1 name, T2 age);void showPerson();T1 m_Name;T2 m_Age;
};// 类模板成员的类外实现(构造函数)
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) :m_Name(name), m_Age(age)
{cout << "构造函数被调用了" << endl;
}
// 类模板成员的类外实现(普通成员函数)
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{cout << "姓名:" << m_Name << "年龄:" << m_Age;
}void test()
{Person<string, int> p("Tom", 28);
}int main()
{test();
}
类模板分文件编写
问题:类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到
解决:解决办法1 :直接包含. cpp源文件解决办法2 :将声明和实现写到同一个文件中,并更改后缀名为. hpp,. hpp是约定的名称,并不是强制
#include <string>
using namespace std;// 第一种解决方式:直接包含源文件
#include "person.cpp"// 第二种解决方式:将.h和.cpp中的内容写在一起,将后缀名改为.hpp文件(约定俗成)
// #include "person.hpp"void test()
{Person<string, int> p("Tom", 28);p.showPerson();
}int main()
{test();
}
#include <iostream>
#include "person.h"// 类模板成员的类外实现(构造函数)
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) :m_Name(name), m_Age(age)
{std::cout << "构造函数被调用了" << std::endl;
}
// 类模板成员的类外实现(普通成员函数)
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{std::cout << "姓名:" << m_Name << " 年龄:" << m_Age << std::endl;
}
#pragma once // 只要在头文件的最开始加入这条预处理指令,就能够保证头文件只被编译一次,防止头文件被重复引用template<class T1, class T2>
class Person
{
public:Person(T1 name, T2 age);void showPerson();T1 m_Name;T2 m_Age;
};
类模板与友元
# include <iostream>
# include <string>
using namespace std;
template < class T1 , class T2 >
class Person ;
template < class T1 , class T2 >
void printPerson2 ( Person< T1, T2> p)
{ cout << "姓名:" << p. m_Name << " 年龄:" << p. m_Age << endl;
} template < class T1 , class T2 >
class Person
{ friend void printPerson ( Person< T1, T2> p) { cout << "姓名:" << p. m_Name << " 年龄:" << p. m_Age << endl; } friend void printPerson2 < > ( Person< T1, T2> p) ; public : Person ( T1 name, T2 age) : m_Name ( name) , m_Age ( age) { cout << "成功构造了一个对象" << endl; } private : T1 m_Name; T2 m_Age;
} ; void test ( )
{ Person< string, int > p1 ( "Jack" , 29 ) ; printPerson ( p1) ; Person< string, int > p2 ( "Tom" , 30 ) ; printPerson2 ( p2) ;
} int main ( )
{ test ( ) ;
}
模板案例
# include <iostream>
# include <string>
# include "MyArray.hpp"
using namespace std;
void test1 ( )
{ MyArray< int > arr1 ( 10 ) ; MyArray< int > arr2 = arr1; MyArray< int > arr3 ( 20 ) ; arr3 = arr1; bool ret; for ( int i = 0 ; i < arr3. getCapacity ( ) ; i++ ) { ret = arr3. append ( 100 - i) ; cout << ret << endl; } cout << "----------" << endl; arr3. pop ( ) ; cout << arr3[ 9 ] << endl; arr3[ 9 ] = 666 ; cout << arr3[ 9 ] << endl;
}
class Person
{
public : Person ( ) { } Person ( string name, int age) { this -> m_Name = name; this -> m_Age = age; } string m_Name; int m_Age;
} ; void test2 ( )
{ MyArray< Person> arr ( 3 ) ; Person p1 ( "Jack" , 25 ) ; Person p2 ( "Tom" , 28 ) ; Person p3 ( "Jim" , 29 ) ; arr. append ( p1) ; arr. append ( p2) ; arr. append ( p3) ; for ( int i = 0 ; i < arr. getCapacity ( ) ; i++ ) { cout << "姓名:" << arr[ i] . m_Name << "\t年龄:" << arr[ i] . m_Age << endl; }
} int main ( )
{ test1 ( ) ; cout << "*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*" << endl; test2 ( ) ; system ( "pause" ) ; return 0 ;
}
# pragma once
# include <iostream>
# include <string> template < class T >
class MyArray
{
private : T* pAddress; int m_Capacity; int m_Size; public : MyArray ( int capacity) { this -> m_Capacity = capacity; this -> m_Size = 0 ; this -> pAddress = new T[ this -> m_Capacity] ; } ~ MyArray ( ) { if ( this -> pAddress != NULL ) { delete [ ] this -> pAddress; this -> pAddress = NULL ; } } MyArray ( const MyArray& arr) { this -> m_Capacity = arr. m_Capacity; this -> m_Size = arr. m_Size; this -> pAddress = new T[ arr. m_Capacity] ; for ( int i = 0 ; i < arr. m_Size; i++ ) { this -> pAddress[ i] = arr. pAddress[ i] ; } } MyArray& operator = ( const MyArray& arr) { if ( this -> pAddress != NULL ) { delete [ ] this -> pAddress; this -> pAddress = NULL ; this -> m_Capacity = 0 ; this -> m_Size = 0 ; } this -> m_Capacity = arr. m_Capacity; this -> m_Size = arr. m_Size; this -> pAddress = new T[ arr. m_Capacity] ; for ( int i = 0 ; i < arr. m_Size; i++ ) { this -> pAddress[ i] = arr. pAddress[ i] ; } return * this ; } bool append ( const T& value) { if ( this -> m_Size == this -> m_Capacity) return false ; this -> pAddress[ m_Size] = value; m_Size++ ; return true ; } void pop ( ) { if ( this -> m_Size == 0 ) return ; m_Size-- ; } T& operator [ ] ( int index) { return this -> pAddress[ index] ; } int getSize ( ) { return this -> m_Size; } int getCapacity ( ) { return this -> m_Capacity; }
} ;