最近在写cpp代码时相创建一个嵌套类,内部类调用外部类的接口,后面实现了特来分享做个记录。
1. 外部类调用内部类
嵌套类,即类A内定义单个或多个类。
显然 只要外部类构造时或创建内部对象即可,外部的生命周期总是大于内部的。
#include <iostream>
class outerClass { // 外部类
public:
outerClass(int num);
~outerClass() = default;
void nestedClass_test();
class nestedClass { // 内部类声明
public:
nestedClass(int num);
~nestedClass() = default;
void test();
private:
int private_num_ = 0;
};
private:
nestedClass nest_; //内部嵌套类对象
};
// 内部类构造函数
outerClass::nestedClass::nestedClass(int num): private_num_(num) {}
// 内部类test()方法
void outerClass::nestedClass::test() {
std::cout << "nestedClass::test private_num: " << private_num_ << std::endl;
}
// 外部类构造函数 与 需要导出的接口
outerClass::outerClass(int num): nest_(num) {}
void outerClass::nestedClass_test() {
nest_.test();
}
int main (int args, char* argv[] ) {
outerClass a = outerClass(1);
a.nestedClass_test();
return 0;
}
2. 外部类调用内部类
一般做法
同理,内部类包含一个外部类的指针来指向外部对象即可。实现内部类通过 outerClass_test 函数调用外部类的 test。
#include <iostream>
class outerClass { // 外部类
public:
outerClass(int num);
~outerClass() = default;
void test();
class nestedClass { // 内部类声明
public:
nestedClass(outerClass*);
~nestedClass() = default;
void outerClass_test();
private:
outerClass* outer_; // 存储外部类对象指针
};
nestedClass nested; //内部嵌套类对象
private:
int private_num = 0;
};
// 内部类构造函数
outerClass::nestedClass::nestedClass(outerClass* o): outer_(o) {}
// 调用外部类test()方法
void outerClass::nestedClass::outerClass_test() {
outer_->test();
}
// 外部类构造函数 与 需要导入的接口
outerClass::outerClass(int num): nested(this), private_num(num){}
void outerClass::test() {
std::cout << "outerClass::test private_num: " << private_num << std::endl;
}
int main (int args, char* argv[] ) {
outerClass a = outerClass(1);
a.nested.outerClass_test();
return 0;
}
这样就可以在OBJ对象的内部,通过 outer_对象
或是封装好的 OuterClass_test 来调用外部的类接口了。
但是这样会不够优雅💩,总是要通过指向一个外部对象来操作,有没有一种更简约的办法呢。
2.1 bind 接口
总所周知,c++11中提供了std::function和std::bind两个方法来对可回调对象进行统一和封装。所以还是以上面的例子,使用bind将外部函数的实现与this绑定到内部准备好的函数接口。如下所示:
为了使案例更具代表性,调用的test函数有两个参数,实现内部类通过 outerClass_test 函数调用外部类的 test
#include <functional>
#include <iostream>
/* 内部嵌套类对象 不存储外部类对象 而是直接构造函数bind对应接口*/
class outerClass { // 外部类
public:
outerClass(int num);
~outerClass() = default;
void test(int a, int b);
class nestedClass { // 内部类声明
public:
nestedClass(std::function<void(int a, int b)>);
~nestedClass() = default;
void outerClass_test(int a, int b);
private:
std::function<void(int a, int b)> import_outerClass_test_;
};
nestedClass nested; //内部嵌套类对象
private:
int private_num = 0;
};
// 内部类构造函数
outerClass::nestedClass::nestedClass(std::function<void(int a, int b)> f) : import_outerClass_test_(f) {}
// 调用外部类test()方法
void outerClass::nestedClass::outerClass_test(int a, int b) {
import_outerClass_test_(a, b);
}
// 外部类构造函数 与 内部类的构造函数直接bind的外部的 test 接口
// bind 中 传入this,后续嵌套的实现直接调 不需要 XX.XX() 调用
outerClass::outerClass(int num): private_num(num),
nested(std::bind(&outerClass::test,
this, std::placeholders::_1, std::placeholders::_2)) {}
void outerClass::test(int a, int b) {
std::cout << "private_num: " << private_num << ", a: " << a << ", b: " << b << std::endl;
std::cout << "outerClass::test private_num * (a + b) = " << private_num * (a + b) << std::endl;
}
int main (int args, char* argv[] ) {
outerClass a = outerClass(2);
a.nested.outerClass_test(1, 2);
return 0;
}