cpp嵌套类调用外部类接口实现方法

最近在写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;
}