源码中属性初始化的方式
cpp
// 1.源码中属性初始化的方式。
#include <iostream>
using namespace std; // 已经声明了
// 人类
class Person {
protected:
// 注意:string 是 std 命名空间里面的成员,C++源码是这种写法std::string
// string内部其实就是对 char*的封装
string name;
int age;
public:
Person(string name, int age) :name(name), age(age) {}
};
// 课程类
class Course {
private:
string name;
public:
Course(string name) :name(name) {}
};
class Student : public Person {
private:
// 如果定义的是对象成员,必须这样初始化(构造函数的后面 : 对象成员(内容)) 使用我们的第二种方式
Course course; // 对象成员
public:
Student(string name, int age, Course course1, string courseNameInfo)
:Person(name, age) // 既然继承了父类就必须给父类的构造函数初始化
// ,
// course(course1) // 第二种方式,编译阶段认可的 对象=对象 对象直接的赋值而已
,
course(courseNameInfo) // 第三种方式, 对象(string内容) 直接初始化Course对象 --- 构造函数
{
// this->course = course1; // 第一种方式(对象=对象) 编译阶段不认可,无法监测到你是否真的给course对象成员初始化了
}
};
int main() {
Course c("C++");
Student student("Derry", 30, c, "NDK内容真多");
return 0;
}
虚继承,二义性
cpp
// 2.虚继承,二义性。 在开发过程中,不准出现,如果出现,要知道怎么回事
#include <iostream>
using namespace std; // 已经声明了
// 租父类
class Object {
public: string info;
};
// 父类1/父类2
class Base1 : virtual public Object {};
class Base2 : virtual public Object {};
// 子类
class Main1 : public Base1, public Base2 {};
int main() {
Object object; // 在栈区开辟,就会有一个this指针,假设指针是1000H,会有指向的能力
Base1 base1; // 在栈区开辟,就会有一个this指针,假设指针是2000H,会有指向的能力
Base2 base2; // 在栈区开辟,就会有一个this指针,假设指针是300H,会有指向的能力
Main1 main1; // 在栈区开辟,就会有一个this指针,假设指针是4000H,会有指向的能力
object.info = "A";
base1.info = "B";
base2.info = "C";
main1.info = "D";
cout << object.info << endl;
cout << base1.info << endl;
cout << base2.info << endl;
cout << main1.info << endl;
exit(0);
}
Main1对象同时继承了Base1和Base2,Base1和Base2都有继承object对应的info,不知道使用哪一个,如果加上virtual就会只会使用一个object副本对应的info
多态
cpp
// 3.多态(虚函数)。 动态多态(程序的角度上:程序在运行期间才能确定调用哪个类的函数 == 动态多态的范畴)
// Java语言默认支持多态
// C++默认关闭多态,怎么开启多态? 虚函数 在父类上给函数增加 virtual关键字
#include <iostream>
using namespace std;
// Android标准
class BaseActivity {
public:
virtual void onStart() {
cout << "BaseActivity onStart" << endl;
}
};
class HomeActivity : public BaseActivity {
public:
void onStart() { // 重写父类的函数
cout << "HomeActivity onStart" << endl;
}
};
class LoginActivity : public BaseActivity {
public:
void onStart() { // 重写父类的函数
cout << "LoginActivity onStart" << endl;
}
};
// 在此函数 体系多态,例如:你传入HomeActivity,我就帮你运行HomeActivity
void startToActivity(BaseActivity * baseActivity) {
baseActivity->onStart();
}
int main() {
// TODO 第一版本
HomeActivity *homeActivity = new HomeActivity();
LoginActivity *loginActivity = new LoginActivity();
startToActivity(homeActivity);
startToActivity(loginActivity);
if (homeActivity && loginActivity) delete homeActivity; delete loginActivity;
cout << endl;
// TODO 第二个版本
BaseActivity * activity1 = new HomeActivity();
BaseActivity * activity2 = new LoginActivity();
startToActivity(activity1);
startToActivity(activity2);
// TODO 抛开 C++ 抛开Java 等等,请问什么是多态? 父类的引用指向之类的对象,同一个方法有不同的实现,重写(动态多态)和 重载(静态多态)
return 0;
}
动态多态:重写在运行期间才能知道调用哪个函数
静态多态
cpp
// 静态多态 (编译期已经决定,调用哪个函数了,这个就属于静态多态的范畴) 重载(静态多态)
#include <iostream>
using namespace std;
void add(int number1, int number2) {
cout << number1 + number2 << endl;
}
void add(float number1, float number2) {
cout << number1 + number2 << endl;
}
void add(double number1, double number2) {
cout << number1 + number2 << endl;
}
int main() {
add(10000, 10000);
add(1.9f, 2.8f);
add(545.4, 654.54);
return 0;
}
静态多态:重载在编译期就能知道调用哪个函数
纯虚函数(Java版抽象类)
cpp
// 5.纯虚函数(Java版抽象类)
// C++纯虚函数(C++没有抽象类) 相当于 Java的抽象类 为了更好理解
#include <iostream>
using namespace std;
// 抽象类/纯虚函数: 分为:1.普通函数, 2.抽象函数/纯虚函数
class BaseActivity {
private:
void setContentView(string layoutResID) {
cout << "XmlResourceParser解析布局文件信息... 反射" << endl;
}
public:
// 1.普通函数
void onCreate() {
setContentView(getLayoutID());
initView();
initData();
initListener();
}
// 纯虚函数是必须继承的(如果子类没有重写纯虚函数,子类就是抽象类), 虚函数是不是不必须的
// 2.抽象函数/纯虚函数
// virtual string getLayoutID(); // 虚函数
virtual string getLayoutID() = 0; // 纯虚函数
virtual void initView() = 0;
virtual void initData() = 0;
virtual void initListener() = 0;
};
// 子类 MainActivity
class MainActivity : public BaseActivity { // MainActivity如果没有重新父类的纯虚函数,自己就相当于 抽象类了
string getLayoutID() {
return "R.layout.activity_main";
}
void initView() {
// Button btLogin = findViewById(R.id.bt_login);
// Button btRegister = findViewById(R.id.bt_register);
// TextView tvInfo = findViewById(R.id.tv_info);
// ... 省略
}
void initData() {
// tvInfo.setText("info...");
// ... 省略
}
void initListener() {
/*btLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 点击做事情
}
});*/
// ... 省略
}
};
// 子类 HomeActivity
class HomeActivity : public BaseActivity { // MainActivity如果没有重新父类的纯虚函数,自己就相当于 抽象类了
string getLayoutID() {
return "R.layout.activity_home";
}
void initView() {
// Button btLogin = findViewById(R.id.bt_login);
// Button btRegister = findViewById(R.id.bt_register);
// TextView tvInfo = findViewById(R.id.tv_info);
// ... 省略
}
void initData() {
// tvInfo.setText("info...");
// ... 省略
}
void initListener() {
/*btLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 点击做事情
}
});*/
// ... 省略
}
};
// 子类 LoginActivity
class LoginActivity : public BaseActivity { // MainActivity如果没有重新父类的纯虚函数,自己就相当于 抽象类了
string getLayoutID() {
return "R.layout.activity_login";
}
void initView() {
// Button btLogin = findViewById(R.id.bt_login);
// Button btRegister = findViewById(R.id.bt_register);
// TextView tvInfo = findViewById(R.id.tv_info);
// ... 省略
}
void initData() {
// tvInfo.setText("info...");
// ... 省略
}
void initListener() {
/*btLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 点击做事情
}
});*/
// ... 省略
}
};
int main() {
// 错误:抽象类型 MainActivity 绝对不能实例化
// MainActivity mainActivity;
// 重新了父类所有的纯虚函数
MainActivity mainActivity;
return 0;
}
全纯虚函数(Java版接口)
cpp
// 虚函数 纯虚函数 全纯虚函数(C++没有接口) 等价于 6.全纯虚函数(Java版接口)。
#include <iostream>
using namespace std;
class Student {
int _id;
string name;
int age;
};
// 此类所有的函数 ,都是纯虚函数,就相当于 Java的接口了
class ISudent_DB {
virtual void insertStudent(Student student) = 0;
virtual void deleteStudent(int _id) = 0;
virtual void updateStudent(int _id, Student student) = 0;
virtual Student queryByStudent(Student student) = 0;
};
// Java的实现类
class Student_DBImpl1 : public ISudent_DB {
public:
void insertStudent(Student student) {
// 插入操作,省略代码...
}
void deleteStudent(int _id) {
// 删除操作,省略代码...
}
void updateStudent(int _id, Student student) {
// 更新操作,省略代码...
}
Student queryByStudent(Student student) {
// 查询操作,省略代码...
}
};
// Java的实现类
class Student_DBImpl2 : public ISudent_DB {
public:
void insertStudent(Student student) {
// 插入操作,省略代码...
}
void deleteStudent(int _id) {
// 删除操作,省略代码...
}
void updateStudent(int _id, Student student) {
// 更新操作,省略代码...
}
Student queryByStudent(Student student) {
// 查询操作,省略代码...
}
};
// Java的实现类
class Student_DBImpl3 : public ISudent_DB {
public:
void insertStudent(Student student) {
// 插入操作,省略代码...
}
void deleteStudent(int _id) {
// 删除操作,省略代码...
}
void updateStudent(int _id, Student student) {
// 更新操作,省略代码...
}
Student queryByStudent(Student student) {
// 查询操作,省略代码...
}
};
int main() {
Student_DBImpl1 studentDbImpl1;
Student_DBImpl2 studentDbImpl2;
Student_DBImpl3 studentDbImpl3;
cout << "Success" << endl;
return 0;
}
回调
cpp
// 7.回调。 Java的登录 简单的 接口
#include <iostream>
using namespace std;
// 登录成功的Bean
class SuccessBean {
public:
string username;
string userpwd;
SuccessBean(string username, string userpwd)
:username(username), userpwd(userpwd) {}
};
// 登录响应的接口 成功,错误
class ILoginResponse {
public:
// 登录成功
virtual void loginSuccess(int code, string message, SuccessBean successBean) = 0;
// 登录失败
virtual void loginError(int code, string message) = 0;
};
// 登录的API动作
void loginAction(string name, string pwd, ILoginResponse & loginResponse) {
if (name.empty() || pwd.empty()) {
cout << "用户名或密码为空!" << endl;
return;
}
if ("Derry" == name && "123" == pwd) {
loginResponse.loginSuccess(200, "登录成功", SuccessBean(name, "恭喜你进入"));
} else {
loginResponse.loginError(404, "登录错误,用户名或密码错误...");
}
}
// 写一个实现类,继承接口
// 接口实现类
class ILoginResponseImpl : public ILoginResponse {
public:
// 登录成功
void loginSuccess(int code, string message, SuccessBean successBean) {
cout << "恭喜登录成功 " << "code:" << code << " message:" << message
<< "successBean:" << successBean.username << "," << successBean.userpwd << endl;
}
// 登录失败
void loginError(int code, string message) {
cout << " 登录失败 " << "code:" << code << " message:" << message << endl;
}
};
int main() {
// 做实验
// Allocating an object of abstract class type 'ILoginResponse'
// 正在分配抽象类型为ILoginResponse的对象 不能被实例化
// 纠结:为什么不可以
// 1.他不是Java的接口,C++也没有接口,他只是像接口而已。
// 2.他也不是抽象类,C++也没有抽象类,他只是像抽象类而已。
// 3.他是纯虚函数的类,此类决定不准你实例化 无论堆区 还是栈区
/*new ILoginResponse() {
// 登录成功
void loginSuccess(int code, string message, SuccessBean successBean) {
}
// 登录失败
void loginError(int code, string message) {
}
}*/
string username;
cout << "请输入用户名.." << endl;
cin >> username;
string userpwd;
cout << "请输入密码.." << endl;
cin >> userpwd;
ILoginResponseImpl iLoginResponse;
loginAction(username, userpwd, iLoginResponse);
return 0;
}
模版函数
cpp
// 8.模版函数(Java版泛型)。 C++没有泛型 C++的模板函数 非常类似于 Java的泛型
#include <iostream>
using namespace std;
// 加分合集 int double float ... 你都要考虑,你是不是要定义很多的 函数
/*void addAction(int n1, int n2) {
cout << "addAction(int n1, int n2):" << n1 + n1 << endl;
}
void addAction(float n1, float n2) {
cout << "addAction(int n1, int n2):" << n1 + n1 << endl;
}
void addAction(double n1, double n2) {
cout << "addAction(int n1, int n2):" << n1 + n1 << endl;
}*/
// 模板函数 == Java的泛型解决此问题
template <typename TT>
void addAction(TT n1, TT n2) {
cout << "模板函数:" << n1 + n2 << endl;
}
int main() {
addAction(1, 2);
addAction(10.2f, 20.3f);
addAction(545.34, 324.3);
addAction<string>("AAA", "BBB");
/*addAction(2, 324.3);
addAction(54, 324.3f);*/
return 0;
}
继承关系的时候,构造函数和析构函数的顺序问题
cpp
// 补充点: 继承关系的时候,构造函数和析构函数 的顺序问题
#include <iostream>
using namespace std;
class Person {
public:
string name;
Person(string name) : name(name) {cout << "Person构造函数" << endl;}
~Person() {cout << "Person析构函数" << endl;}
virtual void test() {
cout << "父 test..." << endl;
}
};
class Student : public Person {
public:
string name;
Student(string name) : Person(name) {
cout << "Student构造函数" << endl;
// Person::test();
}
~Student() {cout << "Student析构函数" << endl;}
void test() {
cout << "子 test..." << endl;
}
};
int main() {
Student student("Derry");
// Person构造函数
// Student构造函数
// Student析构函数
// Person析构函数
Student student1("A");
student1.test();
return 0;
}