从本节开始,将会从面向对象介绍C++。
1、类定义
#ifndef STUDENT.H
#define STUDENT.H
class Student {
int i; //private
public:
Student();
~Student();
private:
int j;
protected:
int k;
public:
int l;
};
#endif // !STUDENT.H
在头文件中定义了类之后,可以在.cpp文件中实现,实现的时候,需要通过命名空间修饰。
#include "Student.h"
#include<iostream>
using namespace std;
Student::Student() {
cout << "构造函数" << endl;
}
Student::~Student() {
cout << "析构函数" << endl;
}
在CMakeLsit.txt
文件中,添加Student.cpp
文件,该文件可执行。
#include "Student.h"
void test() {
Student stu;
}
int main()
{
test();
}
当创建一个Student对象时,会调用构造方法,此时引用对象放在栈中,当test方法调用完毕出栈后,会调用析构函数。
(1)友元函数
在Student
类中,j
属于private
,不能通过对象调用。
void test(Student* student) {
student->j = 100;
}
但是可以通过友元函数,实现调用,在头文件中添加。
friend void test(Student*);
通过添加友元函数,则可以调用Student中的private属性的变量。
Student *student = new Student(1,2);
test(student);
cout << student->getJ() << endl;
delete student;
student = 0;
(2)友元类
当重新创建一个类的时候,如果想要调用其他类的私有属性,也需要将这个类设置为友元类。
class Teacher {
public:
void call(Student *student) {
//不能调用私有j
student->j = 10086;
}
};
friend class Teacher;
(3)单例模式
#ifndef INSTANCE_H
#define INSTANCE_H
class Instance {
private:
static Instance* instance;
Instance();
public:
static Instance* getInstance();
};
#endif // !INSTANCE_H
#include "Instance.h"
Instance* Instance::instance = 0;
Instance::Instance() {
}
Instance *Instance::getInstance() {
if (!instance) {
instance = new Instance;
}
return instance;
}
在C++ 11之后,编译器保证了静态内部变量的线程安全。
2、重载函数 + 操作符重载
在C中是不允许函数重载的,在C++中是允许的,与Java的类似。除了基本的函数重载之外,C++还支持运算符的重载。
#ifndef OPERATOR_H
#define OPERATOR_H
class Test {
public:
int i;
Test();
};
#endif // !OPERATOR_H
Test t1;
t1.i = 100;
Test t2;
t2.i = 200;
Test t3 = t1 + t2;
执行t1 + t2
的想法是:将i
的值相加,然后让t3
的i值为300,。
但是两个对象相加是不可能的,这就涉及到了运算符的重载。
public:
Test operator+(const Test &t1) {
Test temp;
temp.i = this->i + t1.i;
return temp;
}
采用operator
实现+
(加法)运算符的重载,这样就能够实现两个对象的相加,输出i
的和。
3、继承
class Child : Parent{
};
class Parent {
public:
void test();
};
在C++中,继承使用:
来完成,默认情况下是私有继承,当创建一个Child对象的时候,是不能使用父类的test()
方法。
私有继承:不能调用父类的public
、protected
方法。
在Java中是只允许单继承的,但是在C++中可以多继承,可以继承多个父类并实现父类的方法。
class Parent {
public:
void test() {
cout << "Parent" << endl;
}
};
class Child : public Parent {
public:
void test() {
cout << "Child" << endl;
}
};
当子类重写父类的方法时,会执行子类的方法;如果想要执行父类的方法,需要添加Parent::test();
,相当于Java的super。
4、多态
Parent* p = new Child;
p->test();
当执行上面的语句时,这就是类似于Java中的多态,这个时候,会执行父类的test方法,这个就是静态多态。
静态多态:在编译期间,就确定了函数的调用地址。】
也就是在编译期间,指针p指向的就是Parent的内存地址,因此只会执行Parent的方法。
动态多态:在运行时,确定函数的调用地址。 加虚函数
当编译器在运行时,看到p是一个虚函数,会去查找真正的引用地址,就查到了Child。
5、虚函数
纯虚函数就相当于java的抽象方法,在父类中定义了虚函数的时候,必须要在子类中实现 。
class Parent {
public:
virtual void test() {
cout << "Parent" << endl;
}
virtual void add() = 0;
};
class Child : public Parent {
public:
void test() {
//super
Parent::test();
cout << "Child" << endl;
}
void add() {
}
};
6、模板编程
类似于Java的泛型,函数模板就是Java的泛型方法,模板类就是Java的泛型类。
函数模板:使用template
关键字,声明typename
为T的泛型
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
模板类
template <class T,class E>
class Q {
public:
T add(T t, E e) {
return t + e;
}
};
Q<int, float> q;
cout << q.add(1, 1.2f) << endl;
最终可以得到结果:2