circular include dependency?

so i believe this bit of code suffers from circular include dependency after researching pretty much you don't want a blank.h to appear within the same set of .cpp's right? My code is pretty bare, i from reading they point out some pretty obvious errors but in mine i don't understand. By the way i am using QT

profiles.h
1
2
3
4
5
6
7
8
9
10
11
12
13
  #ifndef PROFILES_H
#define PROFILES_H

class Profiles
{
public:
    Profiles();
    QString nprofile_name;
    void profile_set();

};

#endif // PROFILES_H 


profiles.cpp
1
2
3
4
5
6
7
8
9
#include "profiles.h"

Profiles::Profiles()
{
}

void Profiles::profile_set(){

}


createprofilew.cpp edited void CreateProfileW
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "createprofilew.h"
#include "ui_createprofilew.h"
#include "profiles.h

CreateProfileW::CreateProfileW(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CreateProfileW)
{
    ui->setupUi(this);
}

CreateProfileW::~CreateProfileW()
{
    delete ui;
}



void CreateProfileW::on_pushButton_clicked()
{
    Profiles makenew;
    QString profilename;
    profilename= ui->lineEdit_proname->text();
    makenew.nprofile_name=profilename;


}
Last edited on
Including headers from .cpp files should not cause circular dependencies because headers should never include .cpp files.
i keep getting error: C2143: syntax error : missing ';' before '.' i thought in this case it was linked with circular include dependency if it is not what is the issue then
I'd guess the error occurs on line 23 in createprofilew.cpp?
Is Profiles a variable or the class? If it is the class then no, you cannot use it that way. You need a variable
right i set a forward declaration and get

error: C2146: syntax error : missing ';' before identifier 'nprofile_name'

error: C4430: missing type specifier - int assumed. Note: C++ does not support default-int

which points to profiles.h line 8
What "forward declaration"?

Btw, class Profiles has a QString member and therefore profiles.h must include <QString>
You've only shown a single header (profiles.h), so there's no way to know if you have a circular dependency issue. From profiles.h, the only class you reference is QString, so I don't see the possibility of a circular dependency.

My guess is that as keskiverto said you have simply failed to include <qstring.h>. prior to line 8 of profiles.h.




indeed that did fix it. I am just not good at using multiple headers/cpps yet. Last question how should i go about making makenew.nprofile_name readable in another cpp. Since i declared it in void CreateProfileW if i were to declare the class again in another cpp it would be another set of information

nprofile_name is a public member of your Profiles class. Therefore, you can access it directly just as you are doing on line 24 of createprofilew.cpp.

If you want to do this from another .cpp file, you have to make sure that makenew instance is visible in the .cpp file. And yes, if you were to create a new Profiles instance in another .cpp file, that would be a second set of information.





There is no spoon.

.. or in this case there are no files. When your program is running, it is a process in memory -- all in one place. There are no "files" that should "see".

Perhaps this helps: http://www.cplusplus.com/articles/Gw6AC542/


Lets try to make a simple example though.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

void foo ( int & x ) {
  x += 42;
}

int main() {
  int bar = 7;
  int gaz = 0;

  foo( gaz );
  foo( bar );

  std::cout << bar << ' ' << gaz <<'\n';
  return 0;
}

If we look only at the function foo on lines 3-5, there is no sign that the function would see the objects bar and gaz. When main calls foo, the bar and gaz are used as parameters and at that point the foo does "see" those objects.

We could have the lines 3-5 in separate cpp-file. If so, that file clearly would no information whatsoever that there are foo and bar in some other file.

The main() would have to know about foo() though, in order to call it, just like we do introduce std::cout and std::ostream::operator<< with include before we can write line 14. We could either have the declaration of foo void foo(int&); in the file with main() or include a header that has that declaration. The latter is better, because then code in other cpp-files could call this same function.


Did this help to construct a different view to the issue?
Last edited on
not quite understanding including in the header. When i try to do so i get already defined in mainwindow.obj


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef CREATEPROFILEW_H
#define CREATEPROFILEW_H

#include <QDialog>
#include "profiles.h"
Profiles makenew;

namespace Ui {
class CreateProfileW;
}

class CreateProfileW : public QDialog
{
    Q_OBJECT

public:
    explicit CreateProfileW(QWidget *parent = 0);
    ~CreateProfileW();



private slots:
    void on_pushButton_clicked();

private:
    Ui::CreateProfileW *ui;
};

#endif // CREATEPROFILEW_H 


i removed the declaration in the cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "createprofilew.h"
#include "ui_createprofilew.h"

#include "QString"
#include <QDebug>

CreateProfileW::CreateProfileW(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CreateProfileW)
{
    ui->setupUi(this);
}

CreateProfileW::~CreateProfileW()
{
    delete ui;
}



void CreateProfileW::on_pushButton_clicked()
{

    QString profilename;
    profilename= ui->lineEdit_proname->text();
    makenew.nprofile_name=profilename;

    qDebug () << makenew.nprofile_name;


}


mainwindow.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "createprofilew.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    ui->setupUi(this);

    for(int i = 0;i < 5;i++)
    {
        ui->profilebox->addItem(QString::number((i)));
    }
//ui->profilebox->addItem(makenew.nprofile_name);
//qDebug () << makenew.nprofile_name;
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_CreatePro_clicked()
{
    CreateProfileW createP;
    createP.setModal(true);
    createP.exec();
}
i get already defined in mainwindow.obj

That is a linker error.

The compiler has processed mainwindow.cpp. It does contain a global variable "makenew".
The compiler has processed createprofilew.cpp. It does contain a global variable "makenew".
The linker sees thus to different global variables "makenew". That is the error.

C++ standard has ODR (one definition rule). In other words: There can be only one (or heads will fall).


Please, describe the purpose of "makenew".
the idea is that a new window will pop up for user to enter a user name then the user name would appear in a drop down list (combox box in QT) the user name would later be associated with other values like age, address, and more.

So my idea was to make a class that would contain all the info and also be usable/changeable in other windows
createprofilew.h line 6: You're defining makenew as a global. If you include createprofilew.h in multiple .cpp files (which I assume you are), you're creating an instance of makenew in each .cpp file. This is what the linker is objecting to.

Do NOT define global instances in .h files. What you want to do instead is to declare makenew as extern.

createprofilew.h line 6
 
extern Profiles makenew;

This tells the compiler and linker that makenew exists and is defined somewhere else.

Now in one and only one of your .cpp files, you include a single instance of makenew.
 
Profiles makenew;    // In one and only one .cpp file 


Using globals should generally be avoided, but we will leave that discussion for another time.
Last edited on
Topic archived. No new replies allowed.