PDA

View Full Version : undefined reference to MainWindow::server



rz
24th March 2014, 01:05
I declare this in MainWindow.h

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
static serversocket *server;

and in MainWindow.cpp

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);


// serversocket *server = new serversocket();
bool success = server->listen(QHostAddress::Any, 4200);

compiler show the follow error
mainwindow.cpp:14: error: undefined reference to `MainWindow::server'

i don't wana declare server as public variable

ChrisW67
24th March 2014, 03:24
Looks more like a linker error to me. Where is class serversocket implemented and is that part of the link?
Might help to know what platform and toolchain.


i don't wana declare server as public variable
Good. Why declare it static? Why use the pointer uninitialised?

rz
24th March 2014, 23:23
I Use Qt Creator 2.4.1 Based on Qt 4.7.4 (32 bit), in linux enviroment, I use GCC x86 32 bits,

in mainwindow.cpp I have #include "serversocket.h" in mainwindow.h I have include"serversocket.h" too.

If i declare this function as "No Static" I get other error in other form named as logform

void logform::closeEvent(QCloseEvent *event) {

//MainWindow.server
MainWindow::server->LogComunicaoAtivo = false;

// msgi(MainWindow::server->);


}

error: invalid use of non-static data member 'MainWindow::server'

ChrisW67
25th March 2014, 00:08
Where is the implementation of class serversocket? Is it in a separate library? Is it part of the project?


If i declare this function as "No Static" I get other error in other form named as logform
Yes, you do. To access a public member variable of function you need an instance of MainWindow (pointer, reference or actual instance). Perhaps you should pass one as a parameter to the other form. This is basic C++ knowledge and nothing to do with Qt.

rz
25th March 2014, 00:38
serversocket is part of project



{
Q_OBJECT

public:
serversocket(QObject *parent=0);
logform *varLogForm;
bool LogComunicaoAtivo;

private slots:
void readyRead();
void disconnected();
void sendUserList();

protected:
void incomingConnection(int socketfd);


private:
QSet<QTcpSocket*> clients;
QMap<QTcpSocket*,QString> users;

void addLog(QString pText);

};

#endif // SERVERSOCKET_H


I think than you is right about C++, i newby in C++ too,

in main unit i create main window like below

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

MainWindow w;
w.show();


return a.exec();
}

how can I create a MainWindow as new instance instead this way above? I wanna server declared like a public and all other forms need access to him.

ChrisW67
25th March 2014, 01:43
I assume that all the other forms are created by your MainWindow at one time or another. Here is one approach:


class MainWindow: public QMainWindow {
Q_OBJECT

public:
MainWindow(QWidget *p = 0):
QMainWindow(p),
m_server(new serversocket(this)) // the private server created here
{
...
}
private:
serversocket *m_server;
};

// and
class Form: public QWidget {
Q_OBJECT
public:
Form(serversocket *server, QWidget *p = 0): QWidget(p), m_server(server)
{ } // pointer to server kept here

void doStuff() {
m_server->doNetworkyThings() // pointer to server used here
};
private:
serversocket *m_server;
...
};

Then when you create a form in a MainWindow function that needs direct access to the server object:


...
Form *form = new Form(m_server, this); // pointer to server passed into form
...


You may want to ask yourself is exposing the server directly is the best solution.

rz
26th March 2014, 00:36
thanks my friend, but i found a more elegant way to do it.

http://www.codeproject.com/Articles/1921/Singleton-Pattern-its-implementation-with-C

is more easy and clean that your way, but thanks so much for your coperation.

the final result is this

bool success = serversocket::getInstance()->listen(QHostAddress::Any, 4200);

ChrisW67
26th March 2014, 01:12
Using a singleton pattern is one option that works. The pattern potentially comes with downsides in some circumstances that might be worth a few minutes research to see if they apply to you.

wysota
26th March 2014, 15:00
There are people who say that if one has to use the singleton pattern to solve his problem, it usually means the design of the software is broken. As it seems to be here as I don't see any reason for a socket to be a singleton class. In this particular situation it seems to me that the problem is trying to access the socket from within close event (or any other method) of a UI window which does not own the server object. IMHO instead of this a signal should be emitted and caught in some kind of controller having direct access to the server instance.

rz
26th March 2014, 17:26
Dear wysota, I understand your viewpoint, but do you have some suggestion for make class serversocket viewed in any class and form of project? I prefere declare serversocket like a public in mainwindows ?

wysota
27th March 2014, 07:53
but do you have some suggestion for make class serversocket viewed in any class and form of project?

I have a suggestion to not try and make the serversocket instance visible in any class of the project. This breaks at least one of the fundamental object oriented programming rules.

rz
27th March 2014, 11:57
and if I have , any forms and just one connection! how can I do IT ? i need any forms see this connection!

wysota
27th March 2014, 12:25
Why do you "need" all forms to see this connection?

rz
28th March 2014, 23:57
beacause I wanna see log of comunication in one form, when I close form I need set a flag do disable Log,
in other form I wanna test comunication, and due any more reasons from project

wysota
30th March 2014, 07:36
So pass a pointer to the socket manager to each form when you create them.