-1

So I'm fairly new to C++ and I've only started to code into it a few weeks or so. I've been facing a problem that I could not manage to fix. Every time I learned a new programming language, I give myself the challenge to make a little program (not too complex) which groups everything I've learned about that language (functions, classes, arrays, pointers and so on) so I can get a good understand of how actually coding in that language is.

So I decided to make my first C++ program called Chek to check the current MBPS (connection speed) every hour, minutes, or second that the user can input. Like all of my programs, I use a structure that I always use that I discovered while coding in Java (Since I know Java fluidly). Which looks like this:

I've also added a comment of where my issue is in the whole in Lib/Arguments.cpp. Let's say I was to code Chek in Java. I would do my structure like:

Chek or Main class
  |- Core
       |- Core (The class that handles initiating each core's libraries)
       |- Arguments (For parsing, checking and understand arguments)
       |- Broadcast (To print to screen and so on)
       |- Network (For network interaction)
       |- Logs (To save to file logs)
  Then the rest ...

Each Core's lib is handled by the Core, like... To call the Broadcast methods, I would do:

Main().getCore().getBroadcast().BroadcastMsg("Hello!");

So I can access all libraries, methods, and variables without creating deadlocks or any infinite importing loops.

My problem is I'm trying to do this in C++ but it's not working! I've tried a lot of stuff, changing pointers to Object and so on but it doesn't work so I need help!

Here's my code (I'm also using Visual Studio): Chek.cpp:

#include "pch.h"
#include "Main.h"
#include "Core.h"
#include <iostream>

int main(int argc, char *argv[])
{
    Core* Ptr = new Core;
    Main OBJ; Main* Ptr2; Ptr2 = &OBJ;
    std::cout << "Generated PTR's!" << std::endl;
    std::cout << "Core PTR -> " << Ptr << std::endl;
    std::cout << "Main PTR -> " << Ptr2 << std::endl << std::endl;
    Ptr2->SetCrPtr(Ptr);
    Ptr2->loadChek(argv);
}

Main/Main.h:

#pragma once
#ifndef __MAIN_H
#define __MAIN_H

class Core;

class Main
{
public:
    Main();

private:
    Core* CrPtr;

public:
    void loadChek(char *arguments[]);
    void SetCrPtr(Core* Ptr);
    Core* getCrPtr();
};

#endif

Main/Main.cpp:

#include "pch.h"
#include "Main.h"
#include "Core.h"
#include "Arguments.h"
#include "Broadcast.h"
#include <iostream>

using namespace std;

Main::Main() : CrPtr() {};

void Main::SetCrPtr(Core* Ptr)
{
    std::cout << "[Main] Setting CrPtr to " << Ptr << std::endl;
    this->CrPtr = Ptr;
}

Core* Main::getCrPtr() 
{
    return this->CrPtr;
}

void Main::loadChek(char *arguments[])
{
    char *allArguments[sizeof(arguments)];

    this->CrPtr->SetMnPtr(this);
    this->CrPtr->setArguments();
    this->CrPtr->setBroadcast();
    this->CrPtr->getBroadcast()->Log(1, "Loading arguments ...\n");
    this->CrPtr->getArguments()->parseArguments(arguments, allArguments);
}

Core/Core.h:

#pragma once
#ifndef __CLASS_H
#define __CLASS_H
#include "Arguments.h"
#include "Broadcast.h"

class Main;

class Core
{
public:
    Core();

private:
    Main* MnPtr;
    Arguments* ArgPtr;
    Broadcast* BrdPtr;

public:
    Arguments* getArguments();
    void setArguments();
    Broadcast* getBroadcast();
    void setBroadcast();
    void SetMnPtr(Main* Ptr);
};

#endif

Core/Core.cpp:

#include "pch.h"
#include "Core.h"
#include "Main.h"

Core::Core() : MnPtr() {}

void Core::SetMnPtr(Main* Ptr) 
{
    std::cout << "[Core] Setting MnPtr to " << Ptr << std::endl;
    this->MnPtr = Ptr;
}

void Core::setArguments() 
{
    this->ArgPtr = new Arguments;
    std::cout << "[Core] Setting Argument's MnPtr to " << this->MnPtr << std::endl;
    this->ArgPtr->SetMnPtr(this->MnPtr);
}

void Core::setBroadcast()
{
    this->BrdPtr = new Broadcast;
    std::cout << "[Core] Setting Broadcast's MnPtr to " << this->MnPtr << std::endl;
    this->BrdPtr->SetMnPtr(this->MnPtr);
}

Arguments* Core::getArguments()
{
    return ArgPtr;
}

Broadcast* Core::getBroadcast()
{
    return BrdPtr;
}

Lib/Arguments.h:

#pragma once

class Main;

class Arguments
{
public:
    Arguments();

private:
    Main* MnPtr;

public:
    void parseArguments(char *arguments[], char *argumentsElements[]);
    void SetMnPtr(Main* Ptr);
    Main* GetMnPtr();
};

Lib/Arguments.cpp:

#include "pch.h"
#include "Arguments.h"
#include <iostream>

Arguments::Arguments() : MnPtr() {}

void Arguments::SetMnPtr(Main* Ptr)
{
    std::cout << "[Arguments] Setting MnPtr to " << Ptr << std::endl;
    this->MnPtr = Ptr;
}

Main* Arguments::GetMnPtr() 
{
    return this->MnPtr;
}

void Arguments::parseArguments(char *arguments[], char *argumentsElements[])
{
    try {
        if (sizeof(arguments) == 1 || sizeof(arguments) > 4) throw 1;
    }
    catch (int errorCode) {
        if (errorCode == 1) std::cout << "Wrong usage!\n\nUsage: chek.exe <timeout-in-miliseconds> <log-file-path>\nExample: chek.exe 10000 saturday_log_file.txt\n";
    }
    std::cout << "Size -> " << sizeof(arguments) << std::endl;
    for(int i=0; i<sizeof(arguments); i++)
    {
        // The error is produced here, for some reason after MnPtr,
        // nothing is recognised. Like getCrPtr()... has never been declared?
        this->MnPtr->getCrPtr()->getBroadcast()->(1, "Works!");
    }
}

Lib/Broadcast.h:

#pragma once
#include <iostream>
#include "Main.h"

class Broadcast
{
public:
    Broadcast();

private:
    Main* MnPtr;

public:
    void Log(unsigned int statusLevel, std::string message);
    void SetMnPtr(Main* Ptr);
};

Lib/Broadcast.cpp:

#include "pch.h"
#include "Broadcast.h"
#include <iostream>
#include <string>

using namespace std;

Broadcast::Broadcast() : MnPtr() {}

void Broadcast::SetMnPtr(Main* Ptr)
{
    std::cout << "[Broadcast] Setting MnPtr to " << Ptr << std::endl;
    this->MnPtr = Ptr;
}

void Broadcast::Log(unsigned int statusLevel, string message) 
{
    switch (statusLevel) {
    case 1:
        cout << "[.] " << message;
        break;
    case 2:
        cout << "[+] " << message;
        break;
    case 3:
        cout << "[!] " << message;
        break;
    case 4:
        cout << "[X] " << message;
        break;
    }
}

Errors: I get 3 errors.

Visual Studio Error (When you hover it):

Arguments *const this

Pointers to incomplete class is not allowed.

From the error box (Visual Studio):

Error   C2027   use of undefined type 'Main'    Chek2   c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp 30  
Error (active)  E0393   pointer to incomplete class type is not allowed Chek2   C:\Users\xxx\Documents\Programming\C++\VS Workspace\Chek2\Arguments.cpp 30  

Compiler Errors:

1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp(30): error C2027: use of undefined type 'Main'
1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.h(3): note: see declaration of 'Main'

If anyone could help me with this. I would highly appreciate it! I hope it's not too hard of a problem- fairly new to C++ so I don't know exactly what this is compared to Java.

Jessy Guirado
  • 220
  • 1
  • 7
  • 2
    What do you mean by "doesn't work"? Do you get a compiler error? – cigien Aug 18 '20 at 02:53
  • 1
    Make a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) would help. Also post error messages (or phenamona) you have encountered. – Louis Go Aug 18 '20 at 02:55
  • I edited the post adding the errors at the bottom. Sorry. – Jessy Guirado Aug 18 '20 at 03:01
  • In `arguments.cpp` you need to include `Main.h` – drescherjm Aug 18 '20 at 03:25
  • `#include "Main.h"` is not in Arguments.cpp, – Louis Go Aug 18 '20 at 03:29
  • Including ``Main.h`` did not work. – Jessy Guirado Aug 18 '20 at 03:29
  • it doesn't, I've included it like so: ``#include "pch.h" #include "Arguments.h" #include "Main.h" #include `` it still creates a pointer not completed error. Yes, i did try to rebuild it for anyone asking. – Jessy Guirado Aug 18 '20 at 03:32
  • Does the error still say: `error C2027: use of undefined type 'Main'` or does it complain about Core instead? – drescherjm Aug 18 '20 at 03:33
  • ``Visual Studio`` keeps complaining about the same error. But yes @drescherjm you're right. The compiler does complain about core: ``1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\arguments.cpp(31): error C2027: use of undefined type 'Core' 1>c:\users\xxx\documents\programming\c++\vs workspace\chek2\main.h(5): note: see declaration of 'Core'`` – Jessy Guirado Aug 18 '20 at 03:34
  • Then you have to Include Core.h as well for this new error. The previous error was fixed. – drescherjm Aug 18 '20 at 03:35
  • Inside ``arguments.cpp`` or? – Jessy Guirado Aug 18 '20 at 03:36
  • 1
    Yes in `arguments.cpp` right under your `#include "Main.h"` – drescherjm Aug 18 '20 at 03:38
  • Alright, including it in arguments.cpp worked! Thanks @drescherjm. However, if you don't mind, I've got a quick question! The reason why I used forward declaration is that it would create me errors of headers files importing each other. How come, when I add ``#include "Arguments.h"`` into ``Core.cpp`` while also having ``Arguments.cpp`` importing ``Core.h``, how come it creates no errors? – Jessy Guirado Aug 18 '20 at 03:40
  • The forward declarations solve the circular header problem by breaking the loop. In the cpp files you don't have the loop of header dependency. It's very close my time to go to sleep. I hope I made sense. Here is more info [https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) – drescherjm Aug 18 '20 at 03:46
  • Alright, thanks you so much! However you should add your answer as an answer so i can mark is as answered. Cause right now i don't think there's any way i can mark a comment as the answer. – Jessy Guirado Aug 18 '20 at 03:48

1 Answers1

3

Thanks to @drescherjm for answering in comments. I just needed to add:

#include "Main.h"
#include "Core.h"

Inside Arguments.cpp's includes!

Jessy Guirado
  • 220
  • 1
  • 7
  • I am glad you have got your solution and thanks for your sharing, I would appreciate it if you mark them as answer and this will be beneficial to other community. – Barrnet Chou Aug 24 '20 at 06:57