ktd85
asked on
can't call member function of a class-object returned by a function
Getting the following compile-error:
g++ -c -Wall -pthread -I/usr/include/gnet-2.0 -I/usr/lib/gnet-2.0/includ e/ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/includ e -pthread -lgnet-2.0 -lgthread-2.0 -lrt -lglib-2.0 main.cpp -o main.o
main.cpp: In function »int main()«:
main.cpp:9: Fehler: »gruetze.UDPServer::getCl ientManage r« hat keinen Klassentyp
make: *** [main.o] Fehler 1
g++ -c -Wall -pthread -I/usr/include/gnet-2.0 -I/usr/lib/gnet-2.0/includ
main.cpp: In function »int main()«:
main.cpp:9: Fehler: »gruetze.UDPServer::getCl
make: *** [main.o] Fehler 1
//ClientManager Class
class ClientManager{
private:
vector<Client> clients;
public:
ClientManager(void);
bool registerClient(Client test);
int getCount(void);
~ClientManager(void);
};
//Class udpserver
class UDPServer{
private:
int lport;
GUdpSocket* server;
gint ttl;
gint rv;
GInetAddr* addr;
gchar buffer[1024];
pthread_t serverthread;
ClientManager cm;
void* thread();
static void* _run(void* This)
{
return ((UDPServer*)This)->thread();
};
public:
UDPServer(int port);
ClientManager getClientManager();
~UDPServer();
};
//function-code:
ClientManager UDPServer::getClientManager()
{
return this->cm;
}
//Called function:
int ClientManager::getCount(void)
{
return clients.size();
}
//Line containing the error:
printf("%s",gruetze.getClientManager.getCount());
Could you post the complete code ? At least the part where the error occurs (line 9 in main.cpp, as well as the declarations for all variables used, etc.).
ASKER
//main.cpp
#include "udpserver.h"
#include "serial.h"
int main()
{
UDPServer gruetze(1337);
while (true)
{
gruetze.getClientManager();
sleep(100);
}
}
//udpserver.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>
#include <string>
#include "clientmanager.h"
#include <gnet.h>
#include <udp.h>
#include <pthread.h>
class UDPServer{
private:
int lport;
GUdpSocket* server;
gint ttl;
gint rv;
GInetAddr* addr;
gchar buffer[1024];
pthread_t serverthread;
ClientManager cm;
void* thread();
static void* _run(void* This)
{
return ((UDPServer*)This)->thread();
};
public:
UDPServer(int port);
ClientManager getClientManager();
~UDPServer();
};
//udpserver.c
#include "udpserver.h"
using namespace std;
UDPServer::UDPServer(int port)
{
this->lport=port;
gnet_init ();
this->server=gnet_udp_socket_new_with_port(port);
if (this->server == NULL)
{
fprintf (stderr, "Could not create server on port %d\n", port);
exit (EXIT_FAILURE);
}
pthread_create( &serverthread, NULL, _run, this);
}
ClientManager UDPServer::getClientManager()
{
cm.getCount();
return NULL;
//return this->cm;
}
void* UDPServer::thread()
{
while (true)
{
gint bytes_received;
std::string b;
bytes_received = gnet_udp_socket_receive (this->server, this->buffer, sizeof(this->buffer),&this->addr);
b=this->buffer;
b.erase(bytes_received);
if (b.find("ch bin da"))
{
Client m;
cm.registerClient(m);
}
printf("%s",b.c_str());
}
}
UDPServer::~UDPServer() {
pthread_join( serverthread, NULL );
}
I assume that gruetze is an object of type UDPServer ?
Then, if you want to call the getClientManager method on it, you need to do :
gruetze.getClientManager()
instead of :
>> gruetze.getClientManager
Note that the getClientManager method returns a copy of the ClientManager object ... Maybe it should be returned by reference, or by pointer ?
Furthermore, you continue by calling the getCount method on the ClientManager object, but that method returns an int, not the char* that your printf expects (%s).
Then, if you want to call the getClientManager method on it, you need to do :
gruetze.getClientManager()
instead of :
>> gruetze.getClientManager
Note that the getClientManager method returns a copy of the ClientManager object ... Maybe it should be returned by reference, or by pointer ?
Furthermore, you continue by calling the getCount method on the ClientManager object, but that method returns an int, not the char* that your printf expects (%s).
btw, the code you posted is not the same code you posted earlier - it doesn't contain the printf ...
ASKER
oh, sorry. i modified...
So, does that solve your problem ? If not, can you post the new code, as well as the new error message you get ?
ASKER
Corrected the ()-thing.
Is there a method to return the referenc to the original object?
Do have to change the function-call?
Is there a method to return the referenc to the original object?
Do have to change the function-call?
ASKER
addition to my last post. After i corrected the ()-thing the code worked!
Is there a method to return the referenc to the original object?
Do have to change the function-call?
Is there a method to return the referenc to the original object?
Do have to change the function-call?
>> addition to my last post. After i corrected the ()-thing the code worked!
Did you also fix the int vs. %s thing ? By using %d instead of %s for example.
>> Is there a method to return the referenc to the original object?
>> Do have to change the function-call?
It depends what you're trying to do. But you could return a reference to the object instead of a copy to the object, yes. That would indeed involve modifying the method.
Did you also fix the int vs. %s thing ? By using %d instead of %s for example.
>> Is there a method to return the referenc to the original object?
>> Do have to change the function-call?
It depends what you're trying to do. But you could return a reference to the object instead of a copy to the object, yes. That would indeed involve modifying the method.
Type obj;
Type fun_copy() { // <--- return a copy of the object
return obj;
}
Type &fun_ref() { // <--- return a reference to the object
return obj;
}
// and the calling code :
Type obj2 = fun_copy();
obj2.some_method(); // <--- will be called on the copy, not the original object
Type &obj_ref = fun_ref();
obj_ref.some_method(); // <--- will be called on the original object (obj)
ASKER
Yes, i corrected the %d-thing too.
Is there a possibility to make the call in one line?
Type &obj_ref = fun_ref();
obj_ref.some_method();
Is there a possibility to make the call in one line?
Type &obj_ref = fun_ref();
obj_ref.some_method();
>> Is there a possibility to make the call in one line?
Sure :
fun_ref().some_method();
will call the some_method method on the original object (obj).
Sure :
fun_ref().some_method();
will call the some_method method on the original object (obj).
ASKER
I included a message in the constructor and destructor.
After starting the program i'm now receiving masses of the following message:
Client destroyed.
Client destroyed.
Client destroyed.
Client destroyed.
Client destroyed.
Is the refereced object destroyed after the method call?
After starting the program i'm now receiving masses of the following message:
Client destroyed.
Client destroyed.
Client destroyed.
Client destroyed.
Client destroyed.
Is the refereced object destroyed after the method call?
//client.cpp
#include "client.h"
using namespace std;
Client::Client(void)
{
fprintf (stdout, "Client created.\r\n");
}
Client::~Client(void) {
fprintf (stdout, "Client destroyed.\r\n");
}
//changed method:
ClientManager &UDPServer::getClientManager()
{
return this->cm;
}
//main.cpp:
int main()
{
UDPServer gruetze(1337);
while (true)
{
printf("Anzahl der Clients: %d /r/n",gruetze.getClientManager().getCount());
sleep(2);
}
}
>> Client destroyed.
You'll receive one such message each time a Client object is destroyed.
The UDPServer::thread() code you posted earlier has an infinite loop that potentially creates and destroys a Client object for each iteration. That's probably the reason ...
You'll receive one such message each time a Client object is destroyed.
The UDPServer::thread() code you posted earlier has an infinite loop that potentially creates and destroys a Client object for each iteration. That's probably the reason ...
ASKER
Hi,
i think the thread which is started in the udpserver-class does not cause this thing.
I commented out the following line of my main-loop and it stopped producing the messages:
printf("Anzahl der Clients: %d /r/n",gruetze.getClientMan ager().get Count());
any idea?
i think the thread which is started in the udpserver-class does not cause this thing.
I commented out the following line of my main-loop and it stopped producing the messages:
printf("Anzahl der Clients: %d /r/n",gruetze.getClientMan
any idea?
Nothing in the code you posted earlier suggests the creation of Client objects, except for the ones in the thread method.
Maybe you could post the complete, current code ?
Maybe you could post the complete, current code ?
ASKER
yes
//main.cpp
#include "udpserver.h"
#include "serial.h"
int main()
{
UDPServer gruetze(1337);
while (true)
{
//printf("Anzahl der Clients: %d /r/n",gruetze.getClientManager().getCount());
sleep(2);
}
}
//client.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
class Client{
public:
Client(void);
~Client(void);
};
//client.cpp
#include "client.h"
using namespace std;
Client::Client(void)
{
fprintf (stdout, "Client created.\r\n");
}
Client::~Client(void) {
fprintf (stdout, "Client destroyed.\r\n");
}
//clientmanager.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <vector>
#include "client.h"
using namespace std;
class ClientManager{
private:
vector<Client> clients;
public:
ClientManager(void);
bool registerClient(Client test);
int getCount(void);
~ClientManager(void);
};
//clientmanager.cpp
#include "clientmanager.h"
using namespace std;
ClientManager::ClientManager(void)
{
fprintf (stdout, "Client Manager Class created.");
}
bool ClientManager::registerClient(Client test)
{
clients.push_back(test);
return true;
}
int ClientManager::getCount(void)
{
return clients.size();
}
ClientManager::~ClientManager(void) {
fprintf (stdout, "Client Manager Class destroyed.");
}
//udpserver.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <unistd.h>
#include <string>
#include "clientmanager.h"
#include <gnet.h>
#include <udp.h>
#include <pthread.h>
class UDPServer{
private:
int lport;
GUdpSocket* server;
gint ttl;
gint rv;
GInetAddr* addr;
gchar buffer[1024];
pthread_t serverthread;
ClientManager cm;
void* thread();
static void* _run(void* This)
{
return ((UDPServer*)This)->thread();
};
public:
UDPServer(int port);
ClientManager &getClientManager();
~UDPServer();
};
//udpserver.cpp
#include "udpserver.h"
using namespace std;
UDPServer::UDPServer(int port)
{
this->lport=port;
gnet_init ();
this->server=gnet_udp_socket_new_with_port(port);
if (this->server == NULL)
{
fprintf (stderr, "Could not create server on port %d\n", port);
exit (EXIT_FAILURE);
}
pthread_create( &serverthread, NULL, _run, this);
}
ClientManager &UDPServer::getClientManager()
{
return this->cm;
}
void* UDPServer::thread()
{
while (true)
{
gint bytes_received;
std::string b;
if (!gnet_udp_socket_has_packet(this->server))
{
sleep(1);
continue;
}
bytes_received = gnet_udp_socket_receive (this->server, this->buffer, sizeof(this->buffer),&this->addr);
b=this->buffer;
b.erase(bytes_received);
if (b.find("ch bin da"))
{
Client m;
cm.registerClient(m);
}
printf("%s",b.c_str());
}
}
UDPServer::~UDPServer() {
pthread_join( serverthread, NULL );
}
Again, the only location where Client objects are created, is here :
>> Client m;
>> cm.registerClient(m);
Note that registerClient makes two copies of the object passed to it - one temporary copy, and one copy that is saved in the vector.
So, the local m object, and the temporary copy will be destroyed as soon as their context ends, and then the Client objects in the vector are destroyed as soon as the ClientManager object is destroyed.
So ... you should probably make sure that all those temporary objects are not created, and you should probably manage that vector a bit better.
>> Client m;
>> cm.registerClient(m);
Note that registerClient makes two copies of the object passed to it - one temporary copy, and one copy that is saved in the vector.
So, the local m object, and the temporary copy will be destroyed as soon as their context ends, and then the Client objects in the vector are destroyed as soon as the ClientManager object is destroyed.
So ... you should probably make sure that all those temporary objects are not created, and you should probably manage that vector a bit better.
ASKER
Hi,
is there any way to manage to vector without temporary objects?
thx
thomas
is there any way to manage to vector without temporary objects?
thx
thomas
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.