实现一个简单的猫咪🐈类:
c1.h:
#include <iostream>
using namespace std;
class Cat{
public:
Cat(int intialAge);
~Cat();
int getAge() const {
return itsAge;
}
void setAge(int age) {
itsAge = age;
}
void Meow() const {
cout << "Meow \n";
}
private:
int itsAge;
};
c1.cpp
#include "c1.h"
Cat::Cat(int initialAge) {
itsAge = initialAge;
}
Cat::~Cat() {}
int main() {
Cat c(5);
c.Meow();
c.setAge(8);
cout << "now age is " << c.getAge() << endl;
return 0;
}
类的继承和派生:
实现一个父类Mammal, 让Dog继承这个父类:
#include <iostream>
using namespace std;
enum BREED{GOLDEN, DANDIE, LAB};
class Mammal{
public:
Mammal(){};
~Mammal(){};
//访问器和设置器;
int getAge() const {
return itsAge;
};
void setAge();
int getWeight() const {
return itsWeight;
};
void setWeight();
//其它方法;
void speak() const {
cout<<"Mammal sound\n";
};
void sleep() const {
cout<<"Mammal.zZzZ..";
};
protected:
int itsAge;
int itsWeight;
};
//
class Dog : public Mammal{
public:
//初始化狗狗类型
Dog():itsBreed(GOLDEN){
};
~Dog(){};
BREED getBreed() const {
return itsBreed;
}
void setBreed(BREED breed) {
itsBreed = breed;
}
//其它方法
void wagTail() const {
cout<<"wag tail \n";
}
void begForFood() const{
cout<<"begging for food \n";
}
private:
BREED itsBreed;
};
int main() {
Dog d;
d.wagTail();
d.begForFood();
cout << " the breed of dog is ";
cout << d.getBreed();
cout << endl;
return 0;
}
通过继承实现一只小狗🐶 :
#include <iostream>
using namespace std;
enum BREED{GOLDEN, DANDIE, LAB};
class Mammal{
public:
Mammal();
Mammal(int age);
~Mammal(){};
//访问器和设置器;
int getAge() const {
return itsAge;
};
void setAge();
int getWeight() const {
return itsWeight;
};
void setWeight();
//其它方法;
void speak() const {
cout<<"Mammal sound\n";
};
void sleep() const {
cout<<"Mammal.zZzZ..";
};
protected:
int itsAge;
int itsWeight;
};
class Dog : public Mammal{
public:
Dog();
Dog(int age);
Dog(int age , int weight);
Dog(int age, int weight, BREED breed);
BREED getBreed() const {
return itsBreed;
}
void setBreed(BREED breed) {
itsBreed = breed;
}
//其它方法
void wagTail() const {
cout << "wag tail \n";
}
void begForFood() const{
cout << "begging for food \n";
}
void show() {
cout << itsAge << "\n";
cout << itsWeight << "\n";
cout << itsBreed << "\n";
}
private:
BREED itsBreed;
int itsAge;
int itsWeight;
};
Mammal::Mammal():itsAge(1),itsWeight(1) {
cout << "MaMMal constructor" << endl;
}
Mammal::Mammal(int age): itsAge(age), itsWeight(5) {
cout << "MaMMal constructor " << endl;
}
Dog::Dog(){}
Dog::Dog(int age):itsAge(age){}
Dog::Dog(int age, int weight):itsAge(age),itsWeight(weight){}
Dog::Dog(int age, int weight, BREED breed):itsAge(age),itsWeight(weight),itsBreed(breed){}
int main() {
Dog d(2,2,GOLDEN);
d.show();
return 0;
}
使用继承的时候要注意,如果子类使用继承覆盖了父类的一个方法, 父类的其它同名的方法也要覆盖, 如果不希望它们被隐藏, 必须对其进行覆盖:
#include <iostream>
using namespace std;
class Mammal{
public:
Mammal();
~Mammal(){};
//其它方法;
void speak() const {
cout << "Mammal sound\n";
};
void sleep() const {
cout << "Mammal.zZzZ..";
};
void move() const {
cout << "mammal move one step\n";
}
void move(int st) const {
cout << "mammal move "<< st <<" step\n";
}
};
class Dog : public Mammal{
public:
Dog();
~Dog(){};
//其它方法
void wagTail() const {
cout << "wag tail \n";
}
void begForFood() const{
cout << "begging for food \n";
}
void move() const {
cout << "dog move two step\n";
}
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {
Mammal m;
Dog d;
m.move();
d.move();
m.move(2);
//这一句报错了, 因为Dog没有重载Mammal的move( int step)方法
//d.move(2);
return 0;
}
子类要调用父类的相关方法,有两种调用方式,
第一种是:子类.父类方法();
第二种是:子类.父级构造函数::父级方法():
#include <iostream>
using namespace std;
class Mammal{
public:
Mammal();
~Mammal(){};
//其它方法;
void speak() const {
cout << "Mammal sound\n";
};
void sleep() const {
cout << "Mammal.zZzZ..\n";
};
};
class Dog : public Mammal{
public:
Dog();
~Dog(){};
//其它方法
void wagTail() const {
cout << "wag tail \n";
}
void begForFood() const{
cout << "begging for food \n";
}
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {
Dog d;
d.sleep(); //第一种调用方式
d.Mammal::sleep(); //第二种调用方式
return 0;
}
虚拟函数:
如果我创建了一个子类对象, 对象的指针却指向了父类, 问题来了, 我要调用这个实例的方法, 会执行父类的方法,还说子类的方法呢:
#include <iostream>
using namespace std;
class Mammal{
public:
Mammal();
~Mammal(){};
//其它方法;
void speak() const {
cout << "Mammal sound\n";
};
void sleep() const {
cout << "Mammal.zZzZ..\n";
};
};
class Dog : public Mammal{
public:
Dog();
~Dog(){};
//其它方法
void speak() const {
cout << "Dog sound\n";
};
void sleep() const {
cout << "Dog.zZzZ..\n";
};
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {;
Dog d;
d.speak();
d.sleep();
Mammal * m = new Dog();
m->speak();
m->sleep();
return 0;
}
实际上指针是啥类型的, 那么就会调用对应构造函数下的方法;
虚方法的作用就会体现出来,无论指针是指向父类还是子类, 只要确定创建实例的构造函数是哪一个,那么就会调用对应构造函数下的方法,
在父类的构造方法上添加virtual关键字, virtual是可以继承的, 只要父类写了一个virtual, 会自动继承到子类去:
#include <iostream>
using namespace std;
class Mammal{
public:
Mammal();
~Mammal(){};
//其它方法;
virtual void speak() const {
cout << "Mammal sound\n";
};
virtual void sleep() const {
cout << "Mammal.zZzZ..\n";
};
};
class Dog : public Mammal{
public:
Dog();
~Dog(){};
//其它方法
void speak() const {
cout << "Dog sound\n";
};
void sleep() const {
cout << "Dog.zZzZ..\n";
};
};
Mammal::Mammal(){}
Dog::Dog(){}
int main() {;
Dog d;
d.speak();
d.sleep();
Mammal * m = new Dog();
m->speak();
m->sleep();
return 0;
}
虚函数有啥用呢
#include <iostream>
using namespace std;
class Mammal{
public:
Mammal(){};
~Mammal(){};
virtual void sleep() const {
cout << "Mammal.zZzZ..\n";
};
};
class Dog : public Mammal{
public:
Dog(){};
~Dog(){};
void sleep() const {
cout << "Dog.zZzZ..\n";
};
};
class Bird : public Mammal{
public:
Bird(){};
~Bird(){};
void sleep() const {
cout << "Bird.zZzZ..\n";
};
};
int main() {
Mammal* arr[3];
int i;
for(i=0; i<3; i++) {
Mammal* m;
switch(i) {
case 0:
m = new Mammal();
break;
case 1:
m = new Dog();
break;
case 2:
m = new Bird();
break;
}
arr[i] = m;
}
for(i=0; i<3; i++) {
arr[i]->sleep();
}
return 0;
}
只要定义一种数据类型的数组, 数组中的元素全部为子类;
虚函数耶可以作为纯接口函数使用, 子类负责实现:
#include <iostream>
using namespace std;
class Animal{
public:
virtual void eat() = 0;
};
class Cat:public Animal{
public:
void eat() {
cout << "eat it ....ing" << endl;
}
};
int main() {
Cat c;
c.eat();//eat it ....ing
return 0;
}
以下一个案例要了解一下, 当使用虚函数的时候, 如果把子类强转为父类型, 那么就会损失子类定义的方法和属性:
#include <iostream>
using namespace std;
class Mammal{
public:
Mammal(){};
~Mammal(){};
virtual void sleep() const {
cout << "Mammal.zZzZ..\n";
};
};
class Dog : public Mammal{
public:
Dog(){};
~Dog(){};
void sleep() const {
cout << "Dog.zZzZ..\n";
};
};
class Bird : public Mammal{
public:
Bird(){};
~Bird(){};
void sleep() const {
cout << "Bird.zZzZ..\n";
};
};
void refFn(Mammal& m) {
m.sleep();
}
void ptrFn(Mammal* m) {
m->sleep();
}
void slice(Mammal m) {
m.sleep();
}
int main() {
Mammal* arr[3];
int i;
for(i=0; i<3; i++) {
Mammal* m;
switch(i) {
case 0:
m = new Mammal();
break;
case 1:
m = new Dog();
break;
case 2:
m = new Bird();
break;
}
arr[i] = m;
}
for(i=0; i<3; i++) {
//refFn(*arr[i]);
//ptrFn(arr[i]);
slice(*arr[i]);
}
return 0;
}
所以要加油啊
私有继承的方法和属性无法直接访问,只能通过子类的方法访问, 注意下面的private关键字:
#include <iostream>
using namespace std;
//私有继承
class Elec{
public:
Elec() {};
void start() {
cout << "start ....ing" << endl;
}
void stop() {
cout << "stop ....ing" << endl;
}
};
class Fan : private Elec{
public:
void run() {
start();
}
void unRun() {
stop();
}
};
int main() {
Fan f;
f.run();
f.unRun();
//因为使用的是私有继承, 所以无法调用f的start和stop方法;
//f.start();
//f.stop();
return 0;
}
如果不使用继承,通过组合也可以实现效果:
#include <iostream>
using namespace std;
//私有继承
class Elec{
public:
Elec() {};
void start() {
cout << "start ....ing" << endl;
}
void stop() {
cout << "stop ....ing" << endl;
}
};
class Fan{
private:
Elec elec;
public:
void run() {
elec.start();
}
void unRun() {
elec.stop();
}
};
int main() {
//组合的方式实现继承;
Fan f;
f.run();
f.unRun();
return 0;
}
算术运算符的重载, 重载+号:
#include <iostream>
using namespace std;
//重载算术运算符
class Date{
public:
Date();
~Date(){};
Date operator+ (int i) {
cout << "nice gay" << endl;
cout << i << endl;
return *this;
}
};
Date::Date(){};
int main() {
Date date;
date+10;
return 0;
}
重载++运算符:
#include <iostream>
using namespace std;
//重载算术运算符
class Date{
private:
int day;
public:
Date();
~Date(){};
Date operator++ () {
day++;
return *this;
}
int getDay() {
return day;
}
};
Date::Date():day(0){};
int main() {
Date date;
++date;
++date;
cout << "now is " << date.getDay() << endl;
return 0;
}
通过使用智能指针, 可以实现自动释放申请到的内存:
#include <iostream>
using namespace std;
class Dog{
public:
Dog() {
}
~Dog() {
cout << "destructor Dog" << endl;
}
void bark() {
cout << "bark.wa.wa.wa" << endl;
}
};
int main() {
auto_ptr <int> p (new int);
*p = 21;
cout << *p <<endl;
auto_ptr <Dog> pd (new Dog);
pd->bark();
return 0;
}
可以通过一些重载方法,让实例对象转换为数字, 或者让对象转换为字符串:
#include <iostream>
class Dog{
public:
operator int() {
return 100;
}
operator std::string() {
return "abcd";
}
};
int main() {
Dog dg;
int index = dg;
std::cout << "index is " << dg << std::endl;
std::string str(dg);
std::cout << "string is " << str << std::endl;
return 0;
}
在说智能指针之前,有必要复习一下,模版(泛型)的创建, 泛型的实例化:
#include <iostream>
using namespace std;
template<typename T>
class Dog{
private:
T i;
public:
Dog(T _i) {
i = _i;
}
~Dog() {
cout << "destructor Dog" << endl;
}
void bark() {
cout << "my xx is " << i << endl;
}
};
int main() {
Dog<int> d(1);
d.bark();
Dog<char> dd('a');
dd.bark();
return 0;
}
如何去实现一个智能指针, 有了智能指针,就可以防止申请了内存, 又忘记清空:
#include <iostream>
template <typename T>
class smart_pointer{
private:
T* ptr;
public:
smart_pointer(T* p):ptr(p){};
~smart_pointer() {
delete ptr;
}
//smart_pointer& operator=(const smart_pointer& anotherPtr);
T& operator*() {
return *ptr;
}
T* operator->() {
return ptr;
}
};
using namespace std;
class Dog{
public:
Dog() {
}
~Dog() {
cout << "destructor Dog" << endl;
}
void bark() {
cout << "bark.wa.wa.wa" << endl;
}
};
int main() {
//这两种写法都可以
// smart_pointer<Dog> p = new Dog();
smart_pointer<Dog> p(new Dog);
p->bark();
// Dog* d = new Dog();
// d->bark();
return 0;
}
模版关键字:
#include <stdio.h>
template<typename T>
void swap(T & t, T & t1) {
T tmp = t;
t = t1;
t1 = tmp;
return ;
}
int main() {
int i = 1;
int j = 2;
swap<int>(i, j);
printf("%d, %d",i, j);
// cout << i << endl;
// cout << j << endl;
return 0;
}
模版关键字实现一个固定长度的数组:
#include <stdio.h>
#include <iostream>
template<class T>
class Array {
public:
Array();
~Array();
void push(const T& t);
T pop();
private:
int maxSize;
int nowIndex;
T* newData;
};
template<class T>Array<T>::Array():maxSize(100), nowIndex(0) {
newData = new T[maxSize];
std::cout << "new T" << std::endl;
}
template<class T>Array<T>::~Array() {
delete newData;
std::cout << "destructing" << std::endl;
}
template<class T>void Array<T>::push(const T& t) {
newData[nowIndex] = t;
nowIndex = ++nowIndex>=maxSize ? maxSize : nowIndex;
}
template<class T>T Array<T>::pop() {
nowIndex = nowIndex-- >=0 ? nowIndex : 0;
return newData[nowIndex];
}
int main() {
Array<int> array;
array.push(100);
array.push(2);
std::cout << array.pop()+array.pop() << std::endl;
return 0;
}
以上代码的简化版:
#include <stdio.h>
#include <iostream>
template<class T>
class Array {
public:
Array():maxSize(100), nowIndex(0) {
newData = new T[maxSize];
std::cout << "new T" << std::endl;
}
~Array() {
delete newData;
std::cout << "destructing" << std::endl;
}
void push(const T& t) {
newData[nowIndex] = t;
nowIndex = ++nowIndex>=maxSize ? maxSize : nowIndex;
}
T pop() {
nowIndex = nowIndex-- >=0 ? nowIndex : 0;
return newData[nowIndex];
}
private:
int maxSize;
int nowIndex;
T* newData;
};
int main() {
Array<int> array;
array.push(100);
array.push(2);
std::cout << array.pop()+array.pop() << std::endl;
return 0;
}
eof
eof
天道酬勤