vendredi 12 novembre 2021

Seperating C++ Nested Classes into their Own Header Files

new to this site and also C++ but hoping to see some guidance from everyone.

I had a pretty fun project idea to learn C++ digging deeper with APIs, classes, references, etc. and currently I have a working example of code where everything exist within the main.cpp file. The issue I am facing is that when i move the classes (inner and outer) to their own respective header files the code no longer compiles.

The reason for the nested classes is that the OuterAPI serves as the main entry point to the API and has many lower level APIs that can be then accessed beneath it (people, licenes, roles, etc). This way users of API would only have to create an object for the OuterAPI and then dot notation for underlying resource and method.

Here is the working example in the main.cpp

#include <iostream>
#include <nlohmann/json.hpp>
#include <cpr/cpr.h>
using json = nlohmann::json;

class OuterAPI {
private:
    class InnerAPI {
    private:
        OuterAPI& api;
    public:
        InnerAPI(OuterAPI& a) :api(a) {}
        json get() {
            cpr::Response r = cpr::Get(
                cpr::Url{ api.baseUrl + "resource" },
                cpr::Bearer{ api.token }
            );
            return json::parse(r.text)
    };

    std::string token;
    std::string baseUrl = "";
public:
    InnerAPI people;
    OuterAPI(std::string t) : token(t), people(*this) {}
};

int main(int argc, char** argv)
{
    std::string token = "";
    OuterAPI api(token);
    json jsonData = api.people.get();
    std::cout << jsonData.dump(4) << std::endl;

    return 0;
}

Here is me moving everything to respective header/cpp files

OuterAPI.h

#include <nlohmann/json.hpp>
#include <cpr/cpr.h>
using json = nlohmann::json;

class OuterAPI {
private:
    class InnerAPI;
    std::string token;
    std::string baseUrl = "";
public:
    OuterAPI(std::string t);
    ~OuterAPI();
    InnerAPI* people;
};

OuterAPI.cpp

#include "WebexAPI.h"
#include "PeopleAPI.h"

OuterAPI::OuterAPI(std::string t) : token(t) {
    people = new InnerAPI(*this);
}

OuterAPI::~OuterAPI() { delete people; }

InnerAPI.h

#include "OuterAPI.h"

class OuterAPI::InnerAPI {
private:
    OuterAPI& api;
public:
    InnerAPI(OuterAPI& a);
    json get();
};

InnerAPI.cpp

#include "InnerAPI.h"

OuterAPI::InnerAPI::InnerAPI(OuterAPI& a) : api(a) {}

json OuterAPI::InnerAPI::get() {
    cpr::Response r = cpr::Get(
        cpr::Url{ api.baseUrl + "resource" },
        cpr::Bearer{ api.token }
    );
    return json::parse(r.text);

main.cpp (finally) - this is where the compiler error occurs at api.people.get()

int main(int argc, char** argv)
{
    std::string token = "";
    OuterAPI api(token);
    json jsonData = api.people.get();     // COMPILER ERROR "expression must have class type but has type "OuterAPI::InnerAPI *"
    std::cout << jsonData.dump(4) << std::endl;

    return 0;
}

From this I believe the issue is associated with me having to define the InnerAPI object "people" as a pointer but from here I cant seem to come to a resolution.

Also, feel free to critique my design as well, like I say I am new to C++ so want to make sure I can do a good job. Thanks.

Aucun commentaire:

Enregistrer un commentaire