0

I have a dialog window settings that I want to display all values from my breadData object, and to do so I want to have settings inherit breadData's protected members. I try to forward declare breadData, but I'm getting a couple errors in my code.

/home/--/breadPull/prj/settings.h:14: error: invalid use of incomplete type 'struct breadData'
/home/--/breadPull/prj/resultwnd.h:7: error: forward declaration of 'struct breadData'

For one, breadData is not a struct, why does the compiler think breadData is a struct? Secondly I don't understand what the second line is trying to say. My only guess is because there are a lot of circular dependencies in my program. Here's the relevant code:

settings.h

#include <QDialog>
#include "breaddata.h"

class breadData;

namespace Ui {
class Settings;
}

class Settings : public QDialog, public breadData
{
    Q_OBJECT
    //.....

breadData.h

#include <vector>
#include <string>
#include <QtWidgets>
#include <QMainWindow>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "resultwnd.h"
#include "settings.h"


class MainWindow;
class resultWnd;

class breadData
{
public:
    breadData(std::string);
    ~breadData();
    //read in data file that provides all information
    bool readData();

    //.......

resultWnd.h

include <QGroupBox>
#include "breaddata.h"

class breadData;

namespace Ui {
class resultWnd;
}

class resultWnd : public QGroupBox
//.....
Michael
  • 41,989
  • 11
  • 82
  • 128
Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177

2 Answers2

1

You have a circular dependency. breaddata.h includes settings.h before declaring breaddata. settings.h requires the declaration of breaddata for the inheritance.

Thus the file the preprocessor creates when compiling a file that includes breaddata first looks like this (indentation to visualize the recursive insertion of included header files):

<content of breaddata.h>:
    <content of vector, string, QtWidget, QMainWindow, mainwindow.h and ui_mainwindow.h>
    ...
    <content of resultWnd>:
        ...
        class breaddata; //forward declaration mentioned in the error message 
        ...
    <content of settings.h>:
        ...
        class Settings : public QDialog, public breadData //DANG!
        ...
   class breaddata { ... //too late

Summarized:

class breaddata; //forward declaration mentioned in the error message 
...
class Settings : public QDialog, public breadData //DANG!
...
class breaddata { ... //too late

The solution here is to avoid the includes in breaddata.h, especially settings.h. If necessary, forward-declare Settings. The rule of thumb is to include in headers only if you must, and forward-declare whenever you can.

Frank Osterfeld
  • 24,815
  • 5
  • 58
  • 70
1

Your problem is that you have an incomplete understanding of the following:

  1. The precompiler
  2. The difference between declarations and definitions and purpose of using the former.
  3. The purpose and use of namespaces

Without knowing more about your code than what you've shown, the following should solve your problem:

settings.h

#ifndef SETTINGS_H
#define SETTINGS_H

// Your code as above

#endif

breaddata.h

#ifndef BREADDATA_H
#define BREADDATA_H

// Your code as above

#endif

resultWnd.h

#ifndef RESULTWND_H
#define RESULTWND_H

// Your code as above

#endif

I suspect that this will not solve your problem entirely though. Based on your second error message, I suspect you have left important lines of code out of your question so nobody will be able to give you a definitive answer to solve your problem.

I suggest you edit the code in your question to include all lines that contain the breadData, Settings and resultWnd

It is possible to solve this, we just need to see how the three classes are bound together so we can help you untangle them.



The reason the compiler thinks you're using a struct is purely historical. The class keyword was introduced in C++ with the intention to replace the struct. Previously, in C, only the struct keyword exists. As far as I know, the only difference between structs and classes is the default access level. classes default to private while structs default to public. Otherwise, they have identical usage.

RobbieE
  • 4,280
  • 3
  • 22
  • 36